1

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.

2
  • Try to use const a = from(await authService.getToken()); a.subscribe(res => authToken = res) Commented Jun 25, 2024 at 14:02
  • Im getting following errors when making the function async: Type '(req: HttpRequest<unknown>, next: HttpHandlerFn) => Promise<Observable<HttpEvent<unknown>>>' is not assignable to type 'HttpInterceptorFn'. Type 'Promise<Observable<HttpEvent<unknown>>>' is missing the following properties from type 'Observable<HttpEvent<unknown>>': source, operator, lift, subscribe, and 3 more.ts(2322) Commented Jun 25, 2024 at 14:17

2 Answers 2

2

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);
     })
  )
};
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks, but now im getting following error: Type '(req: HttpRequest<unknown>, next: HttpHandlerFn) => Promise<Observable<HttpEvent<unknown>>>' is not assignable to type 'HttpInterceptorFn'.
thank you so much for your anwser and your time, but I cannot use an observable. The function getToken() has to return a promise. This is a requirement. Property 'pipe' does not exist on type 'Promise<unknown>'.ts(23
I didn't test your latest answer yet, i will let you know tomorrow! Thank you in advance for helping!
This works perfectly! I am quite new to angular and ts so I have learned a lot from your answer. Thank you so much!
1

Using map and switchmap rxjs operators, you can try something like this:

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)
    

    // Pass the cloned request with the updated header to the next handler
    return next(req)
        ?.pipe(
            switchMap(() => authService.getToken()),
            map(authToken => {
                // Clone the request and add the authorization header
                const authReq = req.clone({
                    setHeaders: {
                        Authorization: `Bearer ${authToken}`
                    }
                });
                return authReq;
            }),
        );
};

next function return an observable, so you can manipulating for getting authToken value with switchMap operator, then you can use map operator for building authReq and return it.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.