David Karasek
David Karasek

Reputation: 348

Angular interceptor 401 refresh token

Ok, this should be an easy thing to solve, but because of how the app was previously designed it is a little more complicated. Most of the answers I find don't work out for the problem I am trying to solve.

Essentially, I intercept the API calls and when there is a 401 I want to get a new token. The way this app was designed, I have an async action I can call that kicks off the API call to get the new token. It then saves that token in localStorage. There is a flag in the store that tracks the progress of this process. So right now I have to listen to the observable and after it completes grab the new token from localStorage and then make the call again.

Something like this:

this.initRefreshFlag$.subscribe((val, i) => {
    if (val === InitFlagType.Done) {
        const newRequest = request.clone({
            setHeaders: {
                'Authorization':
                `${localStorage.getItem(TOKEN_TYPE)} ${localStorage.getItem(ACCESS_TOKEN_KEY)}`
            }
        });
        return next.handle(newRequest);
    }
});

However, the next.handle() doesn't fire. And I now understand that subscribe is not what I want to use here due to possible memory leaks. I tried using switchMap and mergeMap but they do not fire when the observable this.initRefreshFlag$ changes.

I am at a loss on the best way to proceed here without refactoring a bunch of stuff in the actions/epics. Any suggestions?

Upvotes: 0

Views: 258

Answers (1)

martin
martin

Reputation: 96891

I'm confused what didn't work with switchMap or mergeMap but essentially you can't return anything from subscribe().

In general if you want to execute one Observable, then use its value for something a continue with another Observable you can use mergeMap:

this.initRefreshFlag$.pipe(
  mergeMap(val => {
    const newRequest = request.clone({
      setHeaders: {
        'Authorization': `${localStorage.getItem(TOKEN_TYPE)} ${localStorage.getItem(ACCESS_TOKEN_KEY)}`
      }
    });

    return next.handle(newRequest);
  })
)

Upvotes: 1

Related Questions