Adicionar vários interceptores HTTP ao aplicativo angular


86

Como adicionar vários interceptores HTTP independentes a um aplicativo Angular 4?

Tentei adicioná-los estendendo a providersmatriz com mais de um interceptador. Mas apenas o último é realmente executado, Interceptor1é ignorado.

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

Obviamente, eu poderia combiná-los em uma única Interceptorclasse e isso deve funcionar. No entanto, eu gostaria de evitar isso, já que esses interceptores têm finalidades completamente diferentes (uma para tratamento de erros, outra para mostrar um indicador de carregamento).

Então, como posso adicionar vários interceptores?


2
Você está substituindo Http. Apenas a última substituição é usada. O Interceptor1 não é ignorado, ele simplesmente não existe. Você pode usar o HttpClient que possui interceptores incluídos.
Estus Flask

@estus O que você quer dizer com "Você pode usar HttpClient que tenha interceptores incluídos."?
str


você pode usar diferentes interceptores para solicitação, resposta usando isso com que você pode fazer tratamento de erros, indicador de carregador.
nivas de

Existe alguma atualização sobre esta questão?
Renil Babu

Respostas:


164

Httpnão permite ter mais de uma implementação customizada. Mas, como @estus mencionou, a equipe do Angular adicionou um novo serviço HttpClient recentemente (versão 4.3) que suporta o conceito de múltiplos interceptores. Você não precisa estender o HttpClientcomo faz com o antigo Http. Você pode fornecer uma implementação para, em HTTP_INTERCEPTORSvez disso, que pode ser uma matriz com a 'multi: true'opção:

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

Interceptadores:

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

Esta chamada do servidor imprimirá as mensagens de registro de ambos os interceptores:

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

4
Existe alguma maneira de saber se a apichamada pode ser interceptada por apenas um interceptor? ou por quaisquer condições?
k11k2

@ k11k2 e para todos que procuram, aqui está uma pergunta e resposta sobre isso: stackoverflow.com/questions/45781379/… Admito que ainda estou um pouco confuso sobre isso.
trollkotze

Por que tem que ser @Injectable ()? Funciona sem @Injectable () para mim
makkasi

1
@makkasi: É necessário adicionar @ Injectable se a classe do interceptor precisar fazer qualquer injeção de dependência própria. No exemplo fornecido, não é necessário
jintoppy

1
@ AmirReza-Farahlagha Os interceptores são chamados na ordem em que são fornecidos
hiper2d
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.