Agregue múltiples interceptores HTTP a la aplicación angular


85

¿Cómo agregar múltiples interceptores HTTP independientes a una aplicación de Angular 4?

Intenté agregarlos extendiendo la providersmatriz con más de un interceptor. Pero solo el último se ejecuta realmente, Interceptor1se ignora.

@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, podría combinarlos en una sola Interceptorclase y eso debería funcionar. Sin embargo, me gustaría evitar eso, ya que estos interceptores tienen propósitos completamente diferentes (uno para el manejo de errores, otro para mostrar un indicador de carga).

Entonces, ¿cómo puedo agregar múltiples interceptores?


2
Estás anulando Http. Solo se utiliza la última anulación. El Interceptor1 no se ignora, simplemente no existe. Puede usar HttpClient que tiene interceptores incluidos.
Estus Flask

@estus ¿Qué quiere decir con "Puede usar HttpClient que tiene interceptores incluidos"?
str


puede usar diferentes interceptores para la solicitud, la respuesta usando esto con lo que puede hacer el manejo de errores, indicador de cargador.
nivas

¿Hay alguna actualización sobre esta pregunta?
Renil Babu

Respuestas:


162

Httpno permite tener más de una implementación personalizada. Pero como mencionó @estus, el equipo de Angular ha agregado un nuevo servicio HttpClient recientemente (versión 4.3) que admite el concepto de múltiples interceptores. No es necesario extender el HttpClientcomo lo hace con el antiguo Http. En su lugar, puede proporcionar una implementación HTTP_INTERCEPTORSque puede ser una matriz con la 'multi: true'opción:

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

Interceptores:

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 llamada al servidor imprimirá los mensajes de registro de ambos 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
¿Hay alguna forma de saber que la apillamada puede ser interceptada por solo uno interceptor? o por alguna condición?
k11k2

@ k11k2 y para todos los que buscan, aquí hay una pregunta y una respuesta sobre esto: stackoverflow.com/questions/45781379/… Admito que todavía estoy un poco confundido al respecto.
trollkotze

¿Por qué tiene que ser @Injectable ()? Funciona sin @Injectable () para mí
makkasi

1
@makkasi: Necesita agregar @ Injectable si la clase de interceptor necesita hacer alguna inyección de dependencia propia. En el ejemplo dado, no es obligatorio
jintoppy

¿Cómo solucionar el pedido de interceptores?
AmirReza-Farahlagha
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.