The issue with Angular 5 Interceptor failing to log out upon a server call error

Source : https://gist.github.com/tobbbe/08e01db92c32346b226333a3f952df22

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
           return next.handle(this.addToken(request))
          .pipe(
          catchError((error, ca) => {
            if (error instanceof HttpErrorResponse) {
              switch ((<HttpErrorResponse>error).status) {
                case 401:
                  return this.handle401Error(request, next)
                default:
                  return ErrorObservable.create(error);
              }
            } else {
              return ErrorObservable.create(error);
            }
          })
          )
      }

// Method for 401 Error

  handle401Error(req: HttpRequest<any>, next: HttpHandler) {
        if (this.isRefreshingToken) {
            this.isRefreshingToken = false;

            // Reset here so that the following requests wait until the token
            // comes back from the refreshToken call.
            this.tokenSubject.next(null);
            const http = this.inj.get(HttpClient);

    let customReq: any;   
    let client_secret= 'temp';
    let basicheader = btoa(client_secret);

       return http.get(AppUtils.REFRESH_TOKEN + localStorage.getItem(AppUtils.STORAGE_ACCOUNT_REFRESH_TOKEN), { new HttpHeaders().set('Authorization', 'Basic ' + basicheader)})  // line 38
              .pipe(
                  switchMap((token: any) => {
                    console.log("token " +JSON.stringify(token));
                    if (token) {
                        localStorage.setItem(AppUtils.STORAGE_TOKEN, token["access_token"]);
                        this.tokenSubject.next(token["access_token"]);
                        return next.handle(this.addToken(req));
                    }

                    console.log("refresh failed");
                    // If we don't get a new token, we are in trouble so logout.
                     this.logoutUser();
                      return EmptyObservable.create();

                }, err => {
                    console.log("error calling add category" + JSON.stringify(err));
                   return EmptyObservable.create();
              }),
                catchError(error => {
                    console.log("error  2" +error);
                    // If there is an exception calling 'refreshToken', bad news so logout.
                     this.logoutUser();
                      return EmptyObservable.create();
                }),
                finalize(() => {
                    this.isRefreshingToken = true;
                })
                )
        } else {
                return this.tokenSubject
                .filter(token => token != null)
                .take(1)
                .switchMap(token => {
                    return next.handle(this.addToken(req));
                });


        }

    }

The above code snippet is used to handle the refresh token, reference

If encountering issues like when the line 38 refresh call is successful, the functionality works fine. However, when receiving a 401 error response, the control is not going to the catchError or error block as expected. During debugging, it's difficult to determine where the control goes after failure.

Any insights on what might be going wrong with this implementation? How can one ensure that the control ends up in the error block after receiving a 401 error response? This code is implemented in Angular 5.

You can find the complete code for the request interceptor https://plnkr.co/edit/7ASmr - please note that this is not the working version, just the code snippet.

Answer №1

In order to manage HttpErrorResponse, specifically status codes 401 and 403, I've created an interceptor as follows:

import { Injectable } from '@angular/core';
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor,
  HttpErrorResponse
} from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/do';

import {AuthService} from '../Services/AuthService';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {

  constructor(private auth: AuthService) {}

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

      return next.handle(req).do((event: HttpEvent<any>)  => {},
      (err: any) => {

        if (err instanceof HttpErrorResponse) {

          if (err.status === 401 || err.status == 403) {
            // Your custom code here
          }
        }
      });
    }
}

This interceptor has been added to the providers in the @NgModule (app.module.ts):

providers: [
     // Other providers
    { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
]

It's important to note that the do() operator is utilized for handling error responses (HttpErrorResponse) and must be imported as well.

import 'rxjs/add/operator/do';

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Retrieving a value in the app component from a map using Angular

I have been struggling to display the values of ValueM, ValueR, and product in my app.component.html file. Can anyone offer a solution or tip to help me move forward? Thank you very much. app.component.ts forkJoin( this.service1.method1(filter1), ...

Using Angular with THREE JS integration in Javascript

I am currently experimenting with Angular and facing a challenge that I can't seem to figure out. The issue I am encountering involves integrating a javascript code, SunLight.js, from the repository https://github.com/antarktikali/threejs-sunlight in ...

Modify the color of the downward arrow within a dropdown menu

I'm currently working with ngx paginator and I need to customize the CSS styles to appear in white color. Here is the code I've tried: HTML <div class="paginator__footer-select col col-md-3 offset-md-1 "> & ...

Angular 2 Release Candidate 1 brings a plethora of new features such as multiple components support, a Todo List

Designing a to-do list with the capability to add tasks has been successful so far using one component (Tasklist) and one service (Taskservice). However, upon attempting to divide the functionality into multiple components (Tasklist and Addtask), an issue ...

ngFor returning undefined despite array containing value

While iterating through an array using ngFor, I'm encountering an issue where trying to access data in the 'value' variable results in it being undefined. Why is this happening? myArray = ['a', 'b', 'c', 'd ...

Following an Angular update, the npm installation process encounters issues due to conflicts related to peer dependencies

I am facing challenges with updating my Angular version. When I try to use the command ng update, the output I receive is as follows: Name Version Command to update ------------------------------ ...

Why isn't the Mat error functioning properly in this Angular code?

Could someone explain why the Mat error does not seem to be functioning properly in this Angular code snippet? <div class="form-group"> <mat-form-field class="row-styling"> <mat-label for="aplctnName"> Application Name <sp ...

Before fetching the data from firebase in Angular 2, it is crucial to ensure that the code is properly

I'm facing an issue when trying to retrieve data from Firebase. It successfully retrieves the data, but it takes a few seconds to do so. In the meantime, the code continues running and the variable's value becomes null. Why is this happening? Is ...

Attempting to assign the present value in *ngFor loop to a universal variable

Is there a way to bind the current value in a loop to a component variable in order to pass it to another function when a button outside the loop is pressed? Essentially, I have a menu outside the loop that needs to trigger functions. I have experimented ...

Tips on how to properly format a DateTime String

I need help with formatting a DateTime string retrieved from an API where it is in the format of YYYY-MM-DDTHH:MM:SS +08:00 and I want to change it to DD-MM-YY HH:MM getDataFromApi(res) { this.timestamp = this.timestamp.items[0].timestamp; console ...

Using the ASP.NET parameter or variable in both the application settings and application build events

Is it possible to retrieve an Application Setting from the Pre Build Event in ASP.NET? Can the value of a Setting be injected from the Pre Build Event? Here is the full context: In my project, I have an Angular app integrated within an ASP.NET 4 Web API ...

Angular Material Cards do not expand to fill the entire row

I recently started using Angular Material and I'm attempting to create a page with cards containing photos. However, it seems that by default, the mat-cards stack vertically and do not fill out the space in the row to the right. I've experimented ...

Exploring the incorporation of interfaces into Vue.js/Typescript for variables. Tips?

I have an interface:   export interface TaskInterface{ name: string description1: string time: string } and a component import { TaskInterface } from '@/types/task.interface' data () { return { tasks: [ { name: 'Create ...

sending arguments to angular directive

It was causing me some concern to see the number of global Angular change detections triggered every time an event occurs. That's why I stumbled upon Angular 2 runOutsideAngular still change the UI and decided to implement the 'OutSideEventHandle ...

What is causing the router.events to not fire for FooComponent in my Angular project?

Upon opening the following link , the eventsFromFoo entries in the console are nowhere to be found. It appears that this.router.events is failing to trigger for FooComponent. Any insights on why this might be happening? I am in urgent need of capturing t ...

Importing multiple modules in Typescript is a common practice

I need to include the 'express' module in my app. According to Mozilla's documentation, we should use the following code: import { Application }, * as Express from 'express' However, when using it in TypeScript and VSCode, I enc ...

How can a property be made mandatory in Typescript when another property is set as optional?

Currently, I am unsure about what to search for in order to fulfill the following requirement. Specifically, I am utilizing the given type for react props: interface ComponentProps { message : string, minValue? : number, minValueValidationMessage? ...

Tips for utilizing [ngClass] with various class situations in Angular4

My current div structure is as follows: <div class="class-a" [ngClass]="{'class-b': !person.something}"> However, I now need to add an additional condition... I want the div to have class-a if one condition is met, class-b if another con ...

Get the dynamic type as the return value in a TypeScript abstract class method with generic type T

Within my codebase, I have created an abstract class: export abstract class Filters<P> { protected field: string; protected constructor(field: string) { this.field = field; } protected abstract getFilter(): P; } Additionally, there is ...

Can you explain the significance of ?. in Angular 5?

While I understand that product.id == 1 ? stuff : not stuff simplifies to choosing "stuff" if the id is 1 and "not stuff" otherwise, I am unsure about the meaning of the following code: product?.id.name ...