Apollo-link: accessing client in apollo-link-error onError()

Created on 6 Apr 2018  ·  4Comments  ·  Source: apollographql/apollo-link

Hi,

I have spent several days on this without a success.

What I basically need is to access client, so I can call a mutation to change a global state if there is an error in the arterware.

const client = location => new ApolloClient({
  link: ApolloLink.from([
    onError(({ graphQLErrors, networkError }) => {
      if (graphQLErrors && graphQLErrors.find(isUnauthorized) && !location.pathname.startsWith('/login')) {
        client.resetStore();
        client.mutate({ mutation: notificationAddMutation, variables: { text: 'You did not have rights to this operation. Maybe logged out?' } });
      }
      if (networkError) {
        client.mutate({ mutation: notificationAddMutation, variables: { text: 'There was a network problem. Please check your connection' } });
      }
    }),
    withClientState({
      cache,
      defaults,
      resolvers,
      typeDefs,
    }),
    httpLink,
  ]),
  cache,
});

I get this error: TypeError: client.mutate is not a function

Any ideas how to access client there? Or how to call a local mutation without a client?

Most helpful comment

In your code client is being set to a function that returns an instance of Apollo Client, so I think you will have to do something like:

const clientFunction = location => {
  const client = new ApolloClient({
    link: ApolloLink.from([
      onError(({ graphQLErrors, networkError }) => {
        if (
          graphQLErrors &&
          graphQLErrors.find(isUnauthorized) &&
          !location.pathname.startsWith('/login')
        ) {
          client.resetStore();
          client.mutate({
            mutation: notificationAddMutation,
            variables: {
              text:
                'You did not have rights to this operation. Maybe logged out?',
            },
          });
        }
        if (networkError) {
          client.mutate({
            mutation: notificationAddMutation,
            variables: {
              text: 'There was a network problem. Please check your connection',
            },
          });
        }
      }),
      withClientState({
        cache,
        defaults,
        resolvers,
        typeDefs,
      }),
      httpLink,
    ]),
    cache,
  });
  return client;
};

clientFunction(LOCATION);

All 4 comments

In your code client is being set to a function that returns an instance of Apollo Client, so I think you will have to do something like:

const clientFunction = location => {
  const client = new ApolloClient({
    link: ApolloLink.from([
      onError(({ graphQLErrors, networkError }) => {
        if (
          graphQLErrors &&
          graphQLErrors.find(isUnauthorized) &&
          !location.pathname.startsWith('/login')
        ) {
          client.resetStore();
          client.mutate({
            mutation: notificationAddMutation,
            variables: {
              text:
                'You did not have rights to this operation. Maybe logged out?',
            },
          });
        }
        if (networkError) {
          client.mutate({
            mutation: notificationAddMutation,
            variables: {
              text: 'There was a network problem. Please check your connection',
            },
          });
        }
      }),
      withClientState({
        cache,
        defaults,
        resolvers,
        typeDefs,
      }),
      httpLink,
    ]),
    cache,
  });
  return client;
};

clientFunction(LOCATION);

Thank you very much,

this worked.

For anyone interested:
I am running into lot of issues with afterware and I still have to have substantial logic in each mutation error handler, so I will be probably abandoning the afterware completely and have a function that I will use in each mutation catch block.

Hey I can't seem to get this working

const graphQLClient = new ApolloClient({
  cache: new InMemoryCache(),
  link: ApolloLink.from([
    authLink(graphQLClient),
    refreshLink(graphQLClient),
    httpLink,
  ]),
})

const authLink = (graphQLClient) => setContext(async (req, { headers }) => { ... }
const refreshLink = (graphQLClient) => onError(({ graphQLErrors, networkError, operation, forward }) => { ... }

I have passed graphQLClient to the link functions but graphQLClient is undefined in the links

Was this page helpful?
0 / 5 - 0 ratings