104

How to add multiple, independent HTTP interceptors to an Angular 4 application?

I tried to add them by extending the providers array with more than one interceptors. But only the last one is actually executed, Interceptor1 is ignored.

@NgModule({
  declarations: [ /* ... */ ],
  imports: [ /* ... */ HttpModule ],
  providers: [
    {
      provide: Http,
      useFactory: (xhrBackend: XHRBackend, requestOptions: RequestOptions) =>
        new Interceptor1(xhrBackend, requestOptions),
      deps: [XHRBackend, RequestOptions],
    },
    {
      provide: Http,
      useFactory: (xhrBackend: XHRBackend, requestOptions: RequestOptions) =>
        new Interceptor2(xhrBackend, requestOptions),
      deps: [XHRBackend, RequestOptions]
    },
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

I could obviously combine them into a single Interceptor class and that should work. However, I would like to avoid that as these interceptors have completely different purposes (one for error handling, one to show a loading indicator).

So how can I add multiple interceptors?

5
  • 2
    You're overriding Http. Only last override is used. Interceptor1 is not ignored, it's just non-existent. You can use HttpClient that has interceptors included. Commented Aug 11, 2017 at 11:36
  • @estus What do you mean by "You can use HttpClient that has interceptors included."? Commented Aug 14, 2017 at 6:46
  • angular.io/guide/http Commented Aug 14, 2017 at 6:47
  • you can use different interceptors for request, response using this with that you can do error handling, loader indicator. Commented Aug 14, 2017 at 6:53
  • Is there any update on this question? Commented Jul 3, 2019 at 6:52

1 Answer 1

203
+50

Http doesn't allow to have more than one custom implementation. But as @estus mentioned the Angular team has added a new HttpClient service recently (release 4.3) which supports multiple interceptors concept. You don't need to extend the HttpClient as you do with the old Http. You can provide an implementation for HTTP_INTERCEPTORS instead which can be an array with the 'multi: true' option:

import {HTTP_INTERCEPTORS, HttpClientModule} from '@angular/common/http';
...

@NgModule({
  ...
  imports: [
    ... ,
    HttpClientModule
  ],
  providers: [
    ... ,
    {
      provide: HTTP_INTERCEPTORS,
      useClass: InterceptorOne,
      multi: true,
    },
    {
      provide: HTTP_INTERCEPTORS,
      useClass: InterceptorTwo,
      multi: true,
    }
  ],
  ...
})

Interceptors:

import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http';
...

@Injectable()
export class InterceptorOne implements HttpInterceptor {

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    console.log('InterceptorOne is working');
    return next.handle(req);
  }
}

@Injectable()
export class InterceptorTwo implements HttpInterceptor {

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    console.log('InterceptorTwo is working');
    return next.handle(req);
  }
}

This server call will print both interceptors' log messages:

import {HttpClient} from '@angular/common/http';
...

@Component({ ... })
export class SomeComponent implements OnInit {

  constructor(private http: HttpClient) {}

  ngOnInit(): void {
    this.http.get('http://some_url').subscribe();
  }
}
Sign up to request clarification or add additional context in comments.

6 Comments

Is there any way to tell api call can be intercept by only one interceptor ? or by any conditions ?
@k11k2 and for everyone searching, here is a question and answer about this: stackoverflow.com/questions/45781379/… I admit I'm still a bit confused about it.
Why has to be @Injectable()? It works without @Injectable() for me
@makkasi: Need to add@Injectable if the interceptor class needs to do any dependency injection of its own. In the given example, it is not required
@AmirReza-Farahlagha Interceptors are called in the order in which they are provided
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.