VTEX FastStore v3 - Validate Session Mutation

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.

1 Like