Graphql-code-generator: React-query's mutations variables are not optional

Created on 2 Dec 2020  路  8Comments  路  Source: dotansimha/graphql-code-generator

Describe the bug

Using mutations with react-query, requires you to specify variables in advance, which is not always desirable:

const [login] = useLoginMutation(client, { username: "", password: "" })

Unlike the react-apollo plugin which makes specifying variables in a more declarative way like this:

const [login] = useLoginMutation(client)

// Then provide variables when time comes.
const res = await login({
  username,
  password
});

Environment:

plugins:
  - typescript
  - typescript-operations
  - typescript-react-query
config:
  fetcher: graphql-request
bug plugins

Most helpful comment

Fixed in latest release (major), along with the v3 support.

All 8 comments

The signature should be

useMutation(mutationFn, mutationOptions)

You are totally right. Thank you.
Fixed in: https://github.com/dotansimha/graphql-code-generator/pull/5161

@dotansimha i just tried the fix locally, i can confirm that it is not working.
The variables should not be passed in the useLoginMutation, like this:

export const useLoginMutation = (client: GraphQLClient, variables?: LoginMutationVariables, options?: MutationConfig<LoginMutation, unknown, LoginMutationVariables>) =>
 useMutation<LoginMutation, unknown, LoginMutationVariables>(
    fetcher<LoginMutation, LoginMutationVariables>(client, LoginDocument, variables),
    options
);

But instead, in the fetcher function itself, like this:

function fetcher<TData, TVariables>(client: GraphQLClient, query: string) {
    return async (variables: TVariables): Promise<TData> => client.request<TData, TVariables>(query, variables);
}

@dotansimha I also can confirm that it is not working.

@yassinebridi

I think it should invoke the function client.request immediately.

function fetcher<TData, TVariables>(client: GraphQLClient, query: string) {
    return async (variables: TVariables): Promise<TData> => client.request<TData, TVariables>(query, variables)();
}

This is my fetcher function.

export function fetcher<TData, TVariables>(query: string, variables?: TVariables) {
  return async (): Promise<TData> => {
    const res = await fetch(graphqlEndpoint, {
      method: "POST",
      headers: {
        "content-type": "application/json",
      },
      body: JSON.stringify({ query, variables }),
    });
    const json = await res.json();
    if (json.errors) {
      const { message } = json.errors[0];
      throw new Error(message);
    }
    return json.data;
  };
}

Even though I can skip the variables from the hook function, the mutation fn isn't taking the variables into account. The variables argument is undefined.

Does my fetcher need to change? or is it a bug?

Yeah, we should apply some kind of wrapping to the return value of react-query hook in order to allow to provide variables during execution of the mutation.

Fixed in latest release (major), along with the v3 support.

Was this page helpful?
0 / 5 - 0 ratings