Reputation: 5335
I want to add a Context Link to an existing client's Apollo Link chain.
Here are two GitHub issues I've read through: First, Second.
I do not want to use local storage to store the token as the docs show here.
I have an auth provider which stores my token. After storing my token I'd like to add a Context Link to the Apollo Client's links
const authLink = setContext((_, { headers }) => {
const newHeaders = { ...headers };
if (token) newHeaders.authorization = `Bearer ${token}`;
return {
headers: newHeaders,
};
});
I know I can access the client via useClient
. How do I append this link to the client's already existing from my component without doing it before making the client?
link: authLink.concat(httpLink)
or link: authLink.concat(whateverLinksApolloHas)
Upvotes: 5
Views: 3157
Reputation: 394
As of Apollo Client v3.0.0, you can now update the link chain using the setLink
method on an Apollo Client after it has been created (see Changelog Section v3).
Apollo Client now supports setting a new ApolloLink (or link chain) after new ApolloClient() has been called, using the ApolloClient#setLink method. @hwillson in #6193
However, I have not found any documentation about it other than this though.
I wasn't able to just add a context link using setContext
. Instead, it looks like it replaces the entire link chain, so here was my solution using @apollo/[email protected]
.
import { ApolloClient, HttpLink, NormalizedCacheObject } from '@apollo/client/core';
import { setContext } from '@apollo/client/link/context';
import fetchNewToken from 'your-token-function-file'
const replaceLinkChainOnClient = (client: ApolloClient<NormalizedCacheObject>, url: string) => {
const httpLink: HttpLink = new HttpLink({
uri: url
});
const link = setContext(async (operation, prevContext) => {
const token = await fetchNewToken();
return {
...prevContext,
headers: {
...prevContext.headers,
Authorization: `Bearer ${token}`
}
};
});
client.setLink(link.concat(httpLink));
};
Upvotes: 11
Reputation: 84667
I don't believe there's a supported way of doing what you're trying to do. What you can do is initialize a new instance of ApolloClient
and pass that to ApolloProvider
instead. For example:
const [token, setToken] = useState(null)
const client = getClient(token) // adds the appropriate links as necessary
return <ApolloProvider client={client}><App/></ApolloProvider>
If you go this route and need to keep your cache when the token changes, make sure you utilize the same instance of InMemoryCache
each time you create the client.
However, even this is probably overkill. There's no reason you can't always use setContext
. You're already checking whether token exists before modifying the headers.
Upvotes: 1