web-dev-qa-db-fra.com

Ajouter plusieurs intercepteurs HTTP à Angular Application

Comment ajouter plusieurs intercepteurs HTTP indépendants à une application Angular 4?

J'ai essayé de les ajouter en étendant le tableau providers avec plusieurs intercepteurs. Mais seul le dernier est réellement exécuté, Interceptor1 est ignoré.

@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 {}

Je pourrais évidemment les combiner dans une seule classe Interceptor et cela devrait fonctionner. Cependant, je voudrais éviter cela car ces intercepteurs ont des objectifs complètement différents (un pour la gestion des erreurs, un pour afficher un indicateur de chargement).

Alors, comment puis-je ajouter plusieurs intercepteurs?

63
str

Http ne permet pas d'avoir plus d'une implémentation personnalisée. Mais comme @estus l'a mentionné, l'équipe Angular a ajouté un nouveau service HttpClient (version 4.3) qui prend en charge le concept d'intercepteurs multiples. Vous n'avez pas besoin d'étendre la HttpClient comme avec l'ancien Http. Vous pouvez fournir une implémentation pour HTTP_INTERCEPTORS à la place, qui peut être un tableau avec l'option 'multi: true':

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,
    }
  ],
  ...
})

Les intercepteurs:

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);
  }
}

Cet appel de serveur imprimera les messages du journal des deux intercepteurs:

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();
  }
}
126
hiper2d