loading...
Cover image for Angular: Understanding how interceptors act on HttpRequest and HttpResponse

Angular: Understanding how interceptors act on HttpRequest and HttpResponse

anduser96 profile image Andrei Gatej ・2 min read

You can find a working example here.

Generalization

Assuming that a request will be intercepted by these interceptors:

@NgModule({
    /* ... */
    providers: [
        {
            provide: HTTP_INTERCEPTORS,
            useClass: Interceptor1
            multi: true,
        },
        {
            provide: HTTP_INTERCEPTORS,
            useClass: Interceptor2
            multi: true,
        },
        /* ... */
        {
            provide: HTTP_INTERCEPTORS,
            useClass: InterceptorN
            multi: true,
        }
    ]
    /* ... */
})

When you perform a request by using HttpClient, the provided interceptors will act symmetrically on the whole action(HttpRequest & HttpResponse).

This means that the actual request(HttpRequest) will be intercepted by the interceptors in this order:

INTERCEPTOR_1 -> INTERCEPTOR_2 -> INTERCEPTOR_3 -> ... -> INTERCEPTOR_n

whereas, the path of the response(HttpResponse) will be this:

INTERCEPTOR_n -> ... -> INTERCEPTOR_3 -> INTERCEPTOR_2 -> INTERCEPTOR_1

Alt Text

A practical example

Supposing you have these interceptors:

{ type: 0 } - the request has been dispatched to the backend

export class FooInterceptor implements HttpInterceptor {
  intercept (req: HttpRequest<any>, next: HttpHandler) {
    console.log('[FOO]: request! ')

    return next.handle(req)
      .pipe(
        // Skip `sent` event
        filter(e => e.type !== 0),
        tap((e) => console.log('[FOO]: response!', e)),
      );
  }
}
export class BarInterceptor implements HttpInterceptor {
  intercept (req: HttpRequest<any>, next: HttpHandler) {
    console.log('[BAR]: request! ')

    return next.handle(req)
      .pipe(
        // Skip `sent` event
        filter(e => e.type !== 0),
        tap((e) => console.log('[BAR]: response!', e)),
      );
  }
}
export class BazInterceptor implements HttpInterceptor {
  intercept (req: HttpRequest<any>, next: HttpHandler) {
    console.log('[BAZ]: request! ')

    return next.handle(req)
      .pipe(
        // Skip `sent` event
        filter(e => e.type !== 0),
        tap((e) => console.log('[BAZ]: response!', e)),
      );
  }
}

After dispatching an HTTP request, this will be printed to the console:

[FOO]: request!
[BAR]: request!
[BAZ]: request!

[BAZ]: response!
HttpResponse {  }

[BAR]: response!
HttpResponse {  }

[FOO]: response!
HttpResponse {  }

{userId: 1, id: 1, title: "delectus aut autem", completed: false}

I hope you found this useful. Thanks for reading! :)

Discussion

pic
Editor guide