¿Hay alguna manera de usar los interceptores http de angular para interceptar la respuesta y eliminarla / desecharla, de modo que las futuras devoluciones de llamada descendentes no se ejecuten?

Quiero que se comporte de tal manera que no se ejecute ninguno de los console.log.

this.http.get('/foo').subscribe(
    data => console.log("success", data),
    err => console.log("fail.", err)
);

He visto ejemplos que modifican la respuesta o reemplazan la respuesta con nulo o algún otro valor centinela, pero prefiero no hacer eso porque entonces todos mis controladores de éxito / fracaso deben buscar el centinela, lo que reduce la utilidad de usando un interceptor para manejar ciertas respuestas.

Tengo la sensación de que esto es más una pregunta rxjs y menos una pregunta de interceptor angular, pero todavía no estoy lo suficientemente familiarizado con rx como para estar seguro.

Si importa, estoy usando angular 5.1

1
goat 15 feb. 2018 a las 01:36

2 respuestas

La mejor respuesta

Puede usar Observable.empty para completar la transmisión sin emitir ningún dato. Para combinarlo con HttpInterceptor, encadénelo a next.handle:

return next.handle(req).switchMap(() => Observable.empty());

No sé cómo hacer eso con Promise, lo siento.

1
Harry Ninh 17 feb. 2018 a las 07:31

Encontré otro método que evitará que se llamen las devoluciones de llamada subscribe (). Aquí hay un interceptor de ejemplo que se abstendrá de llamar a suscriptores descendentes si un determinado encabezado http está presente en HttpResponse.

Sin embargo, tenga en cuenta que este método no "descarta la respuesta". En cambio, retrasa indefinidamente la respuesta. Si tiene un código que usa temporizadores (por ejemplo, algún código que generará un error si no se recibe una respuesta de éxito ni de error en 60 segundos), podría ser un problema, porque así es exactamente como funciona este método, simplemente nunca responde.

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(req).pipe(
        switchMap((event: HttpEvent<any>) => {

            // In this example, I only care about checking valid http responses.
            // But, if you also want to inspect errors, you might consider checking for HttpResponseBase or HttpErrorResponse
            if (event instanceof HttpResponse) {

                // Check if this response has a certain http response header set.
                // If so, we throw the response away.
                if (event.headers.has('my-custom-header')) {
                    // We intentionally return an Observable that will never complete. This way,
                    // downstream subscribers will never receive anything, and any .toPromise()
                    // conversions that may be present will also never be invoked because toPromise() only
                    // gets invoked when the Observable completes.
                    // It doesn't actually throw the response away, but rather, it makes the subscribers wait forever, so they will never get a response.
                    // Be careful if you use timeouts.
                    return new Subject<HttpEvent<any>>();
                }

            }

            // The default case - we pass the response back through unmodified.
            return Observable.of(event);
        })
    );
}

// These console.logs will not be called
this.http.get('/foo').subscribe(
    data => console.log("success", data),
    err => console.log("fail.", err)
);

// Neither will these
this.http.get('/foo').toPromise(
    data => console.log("success", data),
    err => console.log("fail.", err)
);
0
goat 15 feb. 2019 a las 04:58