Mihai Alexandru-Ionut
Mihai Alexandru-Ionut

Reputation: 48367

How to prevent duplicated requests for interceptor in Angular?

I have an interceptor which intercepts the 401 error codes received from a 200 OK message.

Unfortunately, I can't modify the API server to return 401 error instead of 200 OK with error code.

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request).pipe(
  switchMap((result: any) => {
    //401 unauthorized error message
    if (result && result.body && result.body.isSuccess == false && result.body.errorCode == '401') {
      return this.unAuthorizedError(request, next);
    } else {
      return next.handle(request);
    }
  }),
  catchError((error) => {
    if (error instanceof HttpErrorResponse) {
      switch ((<HttpErrorResponse>error).status) {
        case 401:
        case 403:
          return this.unAuthorizedError(request, next);
        default:
          break;
      }
    }
    return throwError(error);
  })
);
}

The problem is that every request is send twice and I assume that this is probably due to switchMap method which returns next.handle(request).

I tried with tap method

 tap((result: any) => {
    //401 unauthorized error message
    if (result && result.body && result.body.isSuccess == false && result.body.errorCode == '401') {
      return this.unAuthorizedError(request, next);
    }
  }),

which sends the request only once, but when the token expires then this.unAuthorizedError(request, next) is not called.

Upvotes: 0

Views: 2419

Answers (1)

Andrei Gătej
Andrei Gătej

Reputation: 11934

I think you're right, what next.handle(request); does is to make the request again.

When switchMap's inner observable is created, you already have a response, so I'd say you can replace next.handle() with of(response) so that it can be consumed by which part initiated the request:

/* ... */
return next.handle(request).pipe(
  switchMap((result: any) => {
    //401 unauthorized error message
    if (result && result.body && result.body.isSuccess == false && result.body.errorCode == '401') {
      return this.unAuthorizedError(request, next);
    } else {
      return of(result);
    }
  }),
)
/* ... */

I wrote an article about Angular's HTTPClientModule, here's the section in which I talk about interceptors.

Upvotes: 2

Related Questions