Why do I need a subscribe in my interceptor function?

61 Views Asked by At

All of the examples that I'm following (https://github.com/bartosz-io/jwt-auth-angular), do not have a subscribe in the code, but it is the only way I can get my interceptor function to work. Notice my subscribe() calls. It seems as though I'm not returning something properly, because the code examples do not show that I need to subscribe. I know what subscribe does for an Observable, but shouldn't the interceptor be part of the http calling function subscription?

import {
  HttpEvent,
  HttpInterceptor,
  HttpHandler,
  HttpRequest,
  HttpResponse,
  HttpErrorResponse
} from "@angular/common/http";
import { Injectable } from "@angular/core";
import { BehaviorSubject, Observable, of } from "rxjs";
import { switchMap, filter, take, tap, catchError, mergeMap } from 'rxjs/operators';
import { AuthService } from "./auth.service";
import { MyHttpGetService } from "./http.service";
import { iToken } from "../../interfaces/token.interface";

@Injectable()
export class AddHeaderInterceptor implements HttpInterceptor {
  private isRefreshing = false;
  private refreshTokenSubject: BehaviorSubject<any> = new BehaviorSubject<any>(null);
  private requestArray = [];
  constructor(
    private authenticationService: AuthService,
    private httpApiService: MyHttpGetService,
    ) { }
  intercept(
    request: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    this.refreshTokenSubject.next(null);
    const authToken = this.authenticationService.getToken();
    request = this.addToken(request, authToken);
    return next.handle(request).pipe(
      catchError(async (err: HttpErrorResponse) => {
        if (
          [401, 403].includes(err.status) &&
          !request.url.includes("GetRefreshToken")
        ) {
          console.log('retry here', request);
          return this.handle401Error(request, next);
        } else {
        next.handle(request);
        }
      }
      )
    ) as Observable<HttpEvent<any>>;
  }

  private addToken(request: HttpRequest<any>, authToken: iToken) {
    return request.clone({
      setHeaders: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${authToken.accessToken}`,
      },
    })
  }

  private async handle401Error(request: HttpRequest<any>, next: HttpHandler) {
    const currToken = this.authenticationService.getToken();
    if (!this.isRefreshing) {
      this.isRefreshing = true;
      this.refreshTokenSubject.next(null);
      return this.httpApiService.getAccessToken(currToken).pipe(
        tap((response: any) => {
          this.authenticationService.setAccessToken(response.body);
        }),
        switchMap((res) => {
          this.isRefreshing = false;
          this.refreshTokenSubject.next(res.body);
            return next.handle(this.addToken(request, res.body));
        })).subscribe();
    } else {
      return this.refreshTokenSubject.pipe( 
        tap((token) => console.log('refreshToken else', token)),
        filter(token => token != null),
        take(1),
        switchMap(token => {
          return next.handle(this.addToken(request, token));
        })).subscribe();
    }
  }
}
0

There are 0 best solutions below