Use of Angular HTTP Interceptor | Angular 11

We will discuss Angular HTTP interceptor and look into Angular HTTP error handling, how to make use of an Angular HTTP interceptor in HTTPclient error handling, intercept and modify http response and catch HTTPclient error with a few examples.

Angular HTTP Interceptors provide a flexible way to modify HTTP requests when dealing with network-related resources. The Interceptor can be useful for setting up an Authorization Header across multiple API requests, modifying the response body, error handling in angular API call, throw error and adding logging. Here are a few examples of common use cases for interceptors:

Angular Http Interceptor Retry on Error

Angular HTTP Interceptor Retry on Error any outgoing HTTP request. in the below code snippets we will learn, how do we retry any failed HTTP request by using an interceptor in Angular 11? we’ll use the retryWhen function that triggers when the Observable outgoing request fails.

@Injectable({
    providedIn: 'root'
})
export clas  HttpInterceptor implements HttpInterceptor {
    export const retryCount = 3;
    export const retryWaitTime = 1000;

    intercept(req: HttpRequest <any>, next: HttpHandler) {
        return next.handle(req).pipe(
            retryWhen(error =>
                error.pipe(
                    concatMap((error, count) => {
                        if (count <= retryCount && error.status == 401) {
                            return of(error);
                        }
                        return throwError(error);
                    }),
                    delay(retryWaitTime)
                )
            )
        );
    }
} 

Angular Authorization Header- handle Authentication headers in Angular

This is where you can modify request headers to handle Authentication headers in Angular 11, we generally use Angular HTTP Interceptors for adding them to each request and afterward use Guards for protecting routes. in the below code snippet we are adding an Authorization header with JWT Token if user is logged in.

@Injectable({
    providedIn: 'root'
})
export class JwtTokenInterceptor implements HttpInterceptor {
    constructor(private authService: AuthService) { }

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        
        // add Authorization header with jwt token if account is logged in.        
        const isLoggedIn:boolean = this.authService.isLoggedIn ;
       
        if (isLoggedIn) {
            request = request.clone({
                setHeaders: { Authorization: `Bearer ${this.authService.getToken()}` }
            });
        }

        return next.handle(request);
    }
} 

Angular HTTPClient Error Handling or Catch http error

Angular httpclient error handling, In Angular GET and POST request error handling is done with catchError in which we can handle any type of error as shown below. based on the response error code (like 400,401 or 500) we can display an error message or we can redirect the user to the login page.

Here is an example service which uses this basic form of Angular HTTPclient error handling:


@Injectable({
    providedIn: 'root'
})
export class APIInterceptor implements HttpInterceptor {
    constructor() { }

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return next.handle(req).pipe(catchError(error => this.handleError(error, req, next))
        );
    }
    private handleError(err: HttpErrorResponse, request: HttpRequest<any>, next: HttpHandler): Observable<any> {

        // if token has expired
        if (err.status == 401) {
            // refresh JWT token
        }
        // server error
        else if (err.status == 500) {
            //  handle your server error here
        }
        // rethrow Error
        return throwError(err);
    }
} 

Angular HTTP Interceptor Modify Response

As we already know Angular HTTP interceptor can be used to modify any incoming or outgoing HTTP Requests or Response. when we want to modify with an HTTP response, we have to use RxJs operators and the pipe method.

@Injectable({
    providedIn: 'root'
})
export class APIInterceptor implements HttpInterceptor {
    constructor() { }

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return next.handle(req).pipe(
            map((event: HttpEvent<any>) => {
                if (event instanceof HttpResponse) {
                    event = event.clone({ body: this.handleResponse(event) })
                }
                return event;
            })
        )
    }
    private handleResponse(event: any): any {
        //  override http response body here
        // modfiy projectcode to "P0001"
        const body = { ...event.body, "projectCode": "P0001" };

        return body;
      
    }
} 

Angular Interceptor Manage Logging

We can intercept outgoing requests by using the intercept of the HTTP interceptor class.  for logging requests status, we need to create a service that will implement the HttpIntercepter interface.  in the below code snippet we are trying to log all outgoing requests status, method name, and URL with parameters.

@Injectable({
    providedIn: 'root'
})
export class APIInterceptor implements HttpInterceptor {
    constructor() { }

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return next.handle(req).pipe(
            tap((event: HttpEvent<any>) => {
                if (event instanceof HttpResponse) {
                    this.logResponse(event, req)
                }
            }, error => {
                this.logResponse(error, req);
            })
        )
    }
    private logResponse(res: HttpResponse<any>, req: HttpRequest<any>) {
        console.log(`${req.method} - ${req.urlWithParams} - ${res.status}`);
    }
} 

Setting default timeouts

If we are getting data from the backend that takes some time (more then 2 minutes) to process the request, we can display alert.

@Injectable({
    providedIn: 'root'
})
export clas  HttpInterceptor implements HttpInterceptor {

    intercept(req: HttpRequest <any>, next: HttpHandler) {
        return next.handle(req).pipe(
            timeout(2000)
            catchError(this.handleError) // then handle the error
        );
    }
} 
  • Post category:Angular
  • Reading time:5 mins read