Before, I could do:
networkInterface.use([
{
applyMiddleware(req, next) {
storage.get(STORAGE_KEYS.TOKEN).then(token => {
req.options.headers['Authorization'] = token ? `Bearer ${token}` : null;
next();
});
}
}
]);
Now, if I do:
const authMiddleware = new ApolloLink((operation, forward) => {
return storage.get(STORAGE_KEYS.TOKEN).then(token => {
operation.setContext({
headers: new HttpHeaders().set('Authorization', token ? `Bearer ${token}` : null)
});
return forward(operation);
});
});
I get a typescript error:
Argument of type '(operation: Operation, forward: NextLink) => Promise<Observable<any>>' is not assignable to parameter of type 'RequestHandler'.
Type 'Promise<Observable<any>>' is not assignable to type 'Observable<any>'.
Property 'subscribe' is missing in type 'Promise<Observable<any>>'.
How would I return a promise properly, or execute async code inside the middleware? I know I could get the token first and then apply the middleware, but I want to retrieve the token from storage for each request, i. e. inside the middleware.
Instead of a Promise, return an Observable.
Now you have a Promise that returns an Observable which would cause an error.
Would be nice to have an example somewhere of how to do it with an Observable, but anyway I figured out another way using setContext() from apollo-link-context, which allows to be used with an async function/promise:
import { setContext } from 'apollo-link-context';
const link = this.httpLink.create({ uri: '/graphql' });
const auth = setContext(async (operation, prevContext) => {
const token = await storage.get(STORAGE_KEYS.TOKEN);
return {
headers: new HttpHeaders().set('Authorization', token ? `Bearer ${token}` : null),
// or prevContext.headers.append() if they were already set by a previous middleware
};
});
this.apollo.create({
link: auth.concat(link),
cache: new InMemoryCache(),
});
Thanks @simonhaenisch, that was helpful
Most helpful comment
Would be nice to have an example somewhere of how to do it with an
Observable, but anyway I figured out another way usingsetContext()fromapollo-link-context, which allows to be used with an async function/promise:Related Docs Link