Issue with Faststore Mutations in Custom Components
Hello everyone,
I’m sure we’re all excited about Faststore, and fortunately, I’m already working on a project using it. However, despite the excitement, I’m encountering a significant issue.
Here’s my problem:
If you look at the FastStore documentation, you’ll see two essential mutations:
ValidateSession
ValidateCart
These work perfectly on the FastStore Example Store. However, when I try to use them in a custom component, I run into problems.
Following the documentation on how to use queries and mutations in custom components, I’ve implemented the following code:
import { useLazyQuery_unstable as useLazyQuery } from "@faststore/core/experimental";
const mutation = gql(\`
mutation validateSession($session: IStoreSession!, $search: String!) {
validateSession(session: $session, search: $search) {
postalCode
}
}
`);
const RegionModal = () => {
const [fetchSession, { data, loading, error }] = useLazyQuery(mutation);
const handleRegion = async () => {
await fetchSession({
variables: {
session: payload,
search: "",
},
});
}
}
// Rest of the component
return (...);
};
When I try to run my component, I get the following error:
GraphQLError [Object]: Variable "$search" of required type "String!" was not provided.
Even if I try the same mutation following the schema instructions in Insomnia, the application shows the same error. PS: It doesn’t matter if I pass something into the search string; the error persists as if $search
was not a string.
I tried a different approach by consuming validateSession
as a hook. I imported the three session-related hooks from Faststore:
import {
useSession_unstable as useSession,
validateSession_unstable as validateSession,
sessionStore_unstable as sessionStore,
} from "@faststore/core/experimental";
Using the useSession
hook, we can retrieve the user’s current session and regionalization:
const session = useSession();
Then, we just need to send the new session data with the user’s updated postal code to the validateSession
hook:
if (selectedAddress && session) {
const payload: Partial<Session> = {
addressType: selectedAddress.addressType,
channel: JSON.stringify({
salesChannel: "1",
}),
locale: session.locale,
country: "BRA",
currency: {
code: "BRL",
symbol: "R$",
},
deliveryMode: null,
geoCoordinates: null,
postalCode: selectedAddress.postalCode,
};
console.log("PAYLOAD", payload);
// PS: This will validate the session but not save it!
let data = await validateSession(payload);
Even though the code runs smoothly, the validateSession
hook wasn’t saving the new session data, so every time I called the session, the data remained unchanged.
To resolve this, I used the third hook, sessionStore
. Here’s the source code for it:
export const sessionStore = {
...defaultStore,
set: (val: Session) => {
defaultStore.set(val)
// Trigger cart revalidation when session changes
cartStore.set(cartStore.read())
},
}
This updates the defaultStore
value and forces a cart revalidation. I applied this at the end of my logic to update the session data returned from validateSession
:
// PS: Saves the session returned by ValidateSession
const sessionData = await sessionStore.set(data);
To my surprise, this works perfectly in development.
Now, here’s my question:
After getting this to work in development, whenever I try to build the project, I receive the following error:
Type error: Argument of type '{ locale: string; channel: string; country: string; addressType: string; postalCode: string; deliveryMode: { deliveryChannel: string; deliveryMethod: string; deliveryWindow: { startDate: string; endDate: string; }; }; geoCoordinates: { ...; }; currency: { ...; }; person: { ...; }; }' is not assignable to parameter of type 'Session'.
63 | const validatedSession = await validateSession(newSession)
64 |
> 65 | sessionStore.set(validatedSession ?? newSession)
| ^
66 | } catch (error) {
67 | setErrorMessage(inputFieldErrorMessage)
68 | }
error Command failed with exit code 1.
I have already tried the following:
- Converting the types
- Checking the types
- Ignoring type checks during the build
Additionally, this might be a good time for VTEX to update their Faststore documentation.