How to execute an async fetch request and then retry last failed request?

I’m refreshing the token this way (updated OP’s):

import { ApolloClient } from 'apollo-client';
import { onError } from 'apollo-link-error';
import { ApolloLink, Observable } from 'apollo-link';  // add Observable

// Define Http link
const httpLink = new createHttpLink({
  uri: '/my-graphql-endpoint',
  credentials: 'include'
});

// Add on error handler for apollo link

return new ApolloClient({
  link: ApolloLink.from([
    onError(({ graphQLErrors, networkError, operation, forward }) => {
      // User access token has expired
      if (graphQLErrors && graphQLErrors[0].message === 'Unauthorized') {
        // We assume we have both tokens needed to run the async request
        if (refreshToken && clientToken) {
          // Let's refresh token through async request
          return new Observable(observer => {
            authAPI.requestRefreshToken(refreshToken, clientToken)
              .then(refreshResponse => {
                operation.setContext(({ headers = {} }) => ({
                  headers: {
                    // Re-add old headers
                    ...headers,
                    // Switch out old access token for new one
                    authorization: `Bearer ${refreshResponse.access_token}` || null,
                  }
                }));
              })
              .then(() => {
                const subscriber = {
                  next: observer.next.bind(observer),
                  error: observer.error.bind(observer),
                  complete: observer.complete.bind(observer)
                };

                // Retry last failed request
                forward(operation).subscribe(subscriber);
              })
              .catch(error => {
                // No refresh or client token available, we force user to login
                observer.error(error);
              });
          });
        }
      }
    })
  ])
});

Leave a Comment