Issue
During my angular application startup process, I need to asynchronously get a config file which contains my graphql URI (uri is generated during CI/CD pipeline). To achieve this I can use the APP_INITIALIZER token to do some async loading. This works well enough to setup a default apollo client.
export function createApollo(apolloOptionsService: ApolloOptionsService) {
  return async (): Promise<any> => {
    return await lastValueFrom(apolloOptionsService.createApollo$()
      .pipe(filter(val => !!val))
      .pipe(take(1)));
  };
}
export function getApolloOptions(apolloOptionsService: ApolloOptionsService) {
  return apolloOptionsService.getApolloOtionsValue();
}
@NgModule({
  imports: [ApolloModule, HttpClientModule],
  providers: [
    ApolloOptionsService,
    {
      provide: APP_INITIALIZER,
      useFactory: createApollo,
      deps: [ApolloOptionsService],
      multi: true
    },
    {
      provide: APOLLO_OPTIONS,
      useFactory: getApolloOptions,
      deps: [ApolloOptionsService]
    },
    Apollo
  ]
})
export class GraphQLModule {}
Problem: To get an access token, I need to make a call using the Auth0 library. I cannot use the Auth0 library during the createApollo factory method because the auth0 service hasn't been instantiated yet because of the APP_INITIALIZER startup sequence.
As a work around, I've decided to take the approach of appending the headers at the request level.
return forkJoin([this.userRole$, this.getAccessToken$()])
  .pipe(
    switchMap(res => {
      const roles = res[0];
      const accessToken = res[1] as string;
  return this.apollo
    .watchQuery({
      query: gql`
        ${ApiQueries.getStuff}
      `,
      variables: {
        selected_user_role_id: roles?.rid,
        tenant_id: roles?.tenantId
      },
      context: {
        headers: {
          Authorization: `Bearer ${accessToken}`
        },
      }
    })
    .valueChanges.pipe(
      map((result: any) => {
        return ApiParser.parseStuffResult(result);
      }),
      catchError((error) => this.errorHandler('getStuff$', error)),
    );
})
);
Question:
Appending authorization headers on the request level doesn't work and when inspecting the network tab, i can see my headers aren't there, why?
Is there another way to get access to a jwt during startup?
Side note: I've verified that the headers are present and my requests work if I temporarily hard code a jwt in my apollo client setup
Solution
You want to append headers you should do so in an Apollo-Client link
Here's a simple authLink:
const authLink = setContext(async (_, { headers }) => {
  const token = await getToken(); // or however you get your token
  if (token) headers['Authorization'] = `Bearer ${token}`;
  return { headers };
});
                            Answered By - Michel Floyd
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.