angularasynchronousangular-http-interceptorsangular17

How use async function in angular 17 function based Http Interceptor


I have an interceptor that adds the access token to every request. The only problem is, the only way I can get this access token is by using a function that returns a Promise: async getToken(): Promise<string> {

I HAVE to use this function to get the tokens. There is no other way. I have tried making the authInterceptor function async to no avail.

So how do I use this in a function based interceptor like so?

import { Inject, inject } from '@angular/core';
import { AuthService } from './auth.service';
import { HttpInterceptorFn } from '@angular/common/http';

export const authInterceptor: HttpInterceptorFn = (req, next) => {
  const authService = Inject(AuthService)
  const authToken = await authService.getToken(); // how to do this?? 
  console.log(authToken);

  // Clone the request and add the authorization header
  const authReq = req.clone({
    setHeaders: {
      Authorization: `Bearer ${authToken}`
    }
  });

  // Pass the cloned request with the updated header to the next handler
  return next(authReq);
};

Please help.


Solution

  • You can try using just observables, using switchMap to switch between observables.

    We can use from to convert the promise to an observable.

    One important point is to use inject instead of Inject, first one is used outside the constructor, latter is inside.

    export const authInterceptor: HttpInterceptorFn = (req, next) => { // <- changed here!
      const authService: AuthService = inject(AuthService)
      return from(authService.getToken()).pipe(
         switchMap((authToken: string) => {
              console.log(authToken);
    
              // Clone the request and add the authorization header
              const authReq = req.clone({
                setHeaders: {
                  Authorization: `Bearer ${authToken}`
                }
              });
    
              // Pass the cloned request with the updated header to the next handler  
              return next(authReq);
         })
      )
    };