Iam using Qwik.JS and GraphQL with prisma and i want to make a pop-up ( component) appear whenever my graphQL mutation in trigered :
import { $, type Signal, component$, useSignal, useStore, useTask$ } from "@builder.io/qwik";
import { server$ } from "@builder.io/qwik-city";
import { GraphQLClient } from "graphql-request";
import { Toaster } from "./Toaster";
type ContactCategory = {
id: string;
name: string;
};
type CounterStore = {
count: number;
showToaster: { value: boolean };
categories: ContactCategory[];
categoryId: Signal<string>;
companyName: Signal<string>;
lastName: Signal<string>;
firstName: Signal<string>;
email: Signal<string>;
phone: Signal<string>;
message: Signal<string>;
};
const API_URL = "https://api-inolib.vercel.app/api";
export const registerRequestQrl = server$(async (store: CounterStore) => {
const client = new GraphQLClient(API_URL, { fetch });
try {
const result: { newContactRequest: { id: string } } = await client.request(
/* GraphQL */ `
mutation NewContactRequest(
$categoryId: String!
$companyName: String!
$firstName: String!
$lastName: String!
$email: String!
$phone: String!
$message: String!
) {
newContactRequest(
categoryId: $categoryId
companyName: $companyName
firstName: $firstName
lastName: $lastName
email: $email
phone: $phone
message: $message
) {
id
}
}
`,
{
categoryId: store.categoryId.value,
companyName: store.companyName.value,
firstName: store.firstName.value,
lastName: store.lastName.value,
email: store.email.value,
phone: store.phone.value,
message: store.message.value,
}
);
store.showToaster.value = true;
console.log("result:", result);
console.log("after:", store.showToaster.value);
} catch (error) {
console.error(error);
}
});
export const ContactForm = component$(() => {
const _categoryId = useSignal<string>("");
const _companyName = useSignal<string>("");
const _email = useSignal<string>("");
const _firstName = useSignal<string>("");
const _lastName = useSignal<string>("");
const _message = useSignal<string>("");
const _phone = useSignal<string>("");
const store = useStore<CounterStore>(
{
count: 0,
showToaster: { value: false },
categories: [],
categoryId: _categoryId,
companyName: _companyName,
email: _email,
firstName: _firstName,
lastName: _lastName,
message: _message,
phone: _phone,
},
{ deep: true }
);
const counter$ = $((event: Event) => {
store.count = (event.target as HTMLTextAreaElement).value.length;
});
console.log("before:", store.showToaster.value);
const resetCounter$ = $(() => {
store.count = 0;
});
useTask$(async () => {
const client = new GraphQLClient(API_URL, { fetch });
const result = await client.request<{ contactCategories: ContactCategory[] }>(/* GraphQL */ `
query GetContactCategories {
contactCategories {
id
name
}
}
`);
store.categories = result.contactCategories;
});
return (
<form class="grid-rows-10 mx-[3rem] grid grid-cols-4 py-14 md:w-2/3 md:grid-rows-8 md:px-10">
<div>{store.showToaster.value && <Toaster store={store} />}</div>
As you can see here iam passing the showToaster state into the child component :
import { component$ } from "@builder.io/qwik";
interface ToasterProps {
store: {
showToaster: {
value: boolean;
};
};
}
export const Toaster = component$<ToasterProps>(({ store }) => {
console.log("toasterState:", store.showToaster.value);
return (
<div
id="toast-success"
class="flex items-center w-[15rem] max-w-xs p-4 mb-4 text-gray-500 bg-white rounded-lg shadow dark:text-gray-400 dark:bg-gray-800"
role="alert"
>
<div class="inline-flex items-center justify-center flex-shrink-0 w-8 h-8 text-green-500 bg-green-100 rounded-lg dark:bg-green-800 dark:text-green-200">
<svg
aria-hidden="true"
class="w-5 h-5"
fill="currentColor"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
clip-rule="evenodd"
></path>
</svg>
<span class="sr-only">Check icon</span>
</div>
<div class="ml-3 text-sm font-normal">Formulaire envoyé !</div>
<button
onClick$={() => (store.showToaster.value = false)}
type="button"
class="ml-auto -mx-1.5 -my-1.5 bg-white text-gray-400 hover:text-gray-900 rounded-lg focus:ring-2 focus:ring-gray-300 p-1.5 hover:bg-gray-100 inline-flex h-8 w-8 dark:text-gray-500 dark:hover:text-white dark:bg-gray-800 dark:hover:bg-gray-700"
aria-label="Close"
>
I was expecting the Toaster component to appear after the mutation, but it's not working despite my request being sent. I tried to pass my boolean state by reference by encapsulating it into an object, but it's not working even if the state is currently changing in my console.
before: false
result: { newContactRequest: { id: 'clgote50h0003ms08mhvtvi7t' } }
after: true
I feel like iam missing something, any idea ?