I am trying to refresh access token if current access token is expired.
I am sending multiple requests at one time and I want to make a kind of a queue, so other requests won't request refreshing token route.
I've googled some best practises and examples and found out the following solution for Angular 6 and rxjs v6, which is using BehaviourSubject and switchMaps. (please see attached code)
However I am using Angular 8 (8.1) and rxjs v6.4 and this solution does not work for me.
It simply does not reach switchMap in this.authService.requestAccessToken().pipe. (Tested using console.log)
However if I comment return this.refreshTokenSubject.pipe and return next.handle(request) it reaches that switchMap, but my other requests are failed.
Do you know if anything has been changed or should I try doing this in another way?
- TokenInterceptor
    import { Injectable } from '@angular/core';
    import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
    import { AuthService } from './auth.service';
    import { Observable, BehaviorSubject, Subject } from 'rxjs';
    import { switchMap, take, filter } from 'rxjs/operators';
    @Injectable()
    export class TokenInterceptor implements HttpInterceptor {
        private refreshTokenInProgress = false;
        private refreshTokenSubject: Subject<any> = new BehaviorSubject<any>(null);
        constructor(public authService: AuthService) { }
        intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
            const accessExpired = this.authService.isAccessTokenExpired();
            const refreshExpired = this.authService.isRefreshTokenExpired();
            if (accessExpired && refreshExpired) {
                return next.handle(request);
            }
            if (accessExpired && !refreshExpired) {
                if (!this.refreshTokenInProgress) {
                    this.refreshTokenInProgress = true;
                    this.refreshTokenSubject.next(null);
                    return this.authService.requestAccessToken().pipe(
                        switchMap((authResponse) => {
                            this.authService.saveToken(AuthService.TOKEN_NAME, authResponse.accessToken);
                            this.authService.saveToken(AuthService.REFRESH_TOKEN_NAME, authResponse.refreshToken);
                            this.refreshTokenInProgress = false;
                            this.refreshTokenSubject.next(authResponse.refreshToken);
                            return next.handle(this.injectToken(request));
                        }),
                    );
                } else {
                    return this.refreshTokenSubject.pipe(
                        filter(result => result !== null),
                        take(1),
                        switchMap((res) => {
                            return next.handle(this.injectToken(request))
                        })
                    );
                }
            }
            if (!accessExpired) {
                return next.handle(this.injectToken(request));
            }
        }
        injectToken(request: HttpRequest<any>) {
            const token = this.authService.getToken(AuthService.TOKEN_NAME);
            return request.clone({
                setHeaders: {
                    Authorization: `Bearer ${token}`
                }
            });
        }
    }
- requestAccessToken
    requestAccessToken(): Observable<any> {
        const refreshToken = this.getToken(AuthService.REFRESH_TOKEN_NAME);
        return this.http.post(`${this.basePath}/auth/refresh`, { refreshToken });
    }
UPD 1
So I used these sources to write my interceptor:
- https://itnext.io/angular-tutorial-implement-refresh-token-with-httpinterceptor-bfa27b966f57 (Angular 4 solution, I believe it edpends on rxjs version) 
- https://github.com/melcor76/interceptors/blob/master/src/app/interceptors/auth.interceptor.ts 
UPD 2
I've excluded refresh request from interceptor scope and now it's working
Thanks to @JBNizet
 
     
    