En la documentación sobre el nuevo HttpClientModule incluido en la nueva versión de Angular 4.3 se explica muy bien el mecanismo para interceptar solicitudes. También se menciona el mecanismo interceptor de respuesta, sin embargo, no puedo encontrar nada al respecto.
¿Alguien tiene alguna idea sobre cómo interceptar una respuesta para modificar el cuerpo del mensaje antes de enviarlo al servicio?
Gracias.
Recientemente creé un HttpInterceptor para resolver referencias cíclicas en algunos JSON en el lado del cliente, esencialmente reemplazando cualquier objeto con una propiedad $ref con el objeto en el JSON que tiene una propiedad $id coincidente. (Este es el resultado que obtiene si Json.Net está configurado con PreserveReferencesHandling.Objects y ReferenceLoopHandling.Ignore ).
Las respuestas aquí me ayudaron de alguna manera, pero ninguna de ellas muestra cómo modificar el cuerpo de la respuesta, como necesita el OP. Para hacerlo, uno necesita clonar el evento y actualizar el cuerpo, así:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { return next.handle(req).map(event => { if (event instanceof HttpResponse && shouldBeIntercepted(event)) { event = event.clone({ body: resolveReferences(event.body) }) } return event; }); }Cualquier evento que no deba modificarse simplemente pasa al siguiente controlador.
Supongo que puede usar do como sugirió @federico-scamuzzi, o puede usar map y catch así:
import { Injectable } from '@angular/core'; import { HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator/catch'; import 'rxjs/add/observable/throw'; @Injectable() export class AuthInterceptor implements HttpInterceptor { intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { console.info('req.headers =', req.headers, ';'); return next.handle(req) .map((event: HttpEvent<any>) => { if (event instanceof HttpResponse && ~~(event.status / 100) > 3) { console.info('HttpResponse::event =', event, ';'); } else console.info('event =', event, ';'); return event; }) .catch((err: any, caught) => { if (err instanceof HttpErrorResponse) { if (err.status === 403) { console.info('err.error =', err.error, ';'); } return Observable.throw(err); } }); } } EDITAR: @LalitKushwah estaba preguntando sobre la redirección if(!loggedIn) . Uso Route Guards , específicamente:
import { Injectable } from '@angular/core'; import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router'; import { Observable } from 'rxjs/Observable'; import { AuthService } from '../../api/auth/auth.service'; import { AlertsService } from '../alerts/alerts.service'; @Injectable() export class AuthGuard implements CanActivate { constructor(private router: Router, private alertsService: AlertsService) {} canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot ): Observable<boolean> | Promise<boolean> | boolean { if (AuthService.loggedIn()) return true; const url: string = state.url; this.alertsService.add(`Auth required to view ${url}`); this.router .navigate(['/auth'], { queryParams: { redirectUrl: url } }) .then(() => {}); return false; } }Entonces simplemente puedo agregar eso como un argumento a mi ruta:
{ path: 'dashboard', loadChildren:'app/dashboard/dashboard.module#DashboardModule', canActivate: [AuthGuard] }Desde el lanzamiento de Angular 6, RxJs 6.0 cambió su interfaz, por lo que no puede usar operadores de la misma manera (como .map() , .tap() ...).
Por eso, la mayoría de las soluciones anteriores están desactualizadas.
Así es como modifica correctamente el contenido de un Observable usando RxJs 6.0+ (con pipe ):
import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse} from '@angular/common/http'; import {Injectable} from '@angular/core'; import {Observable} from 'rxjs'; import {map} from 'rxjs/operators'; @Injectable() export class ResponseInterceptor implements HttpInterceptor { intercept(req: HttpRequest, next: HttpHandler): Observable<HttpEvent<any>> { return next.handle(req).pipe(map((event: HttpEvent<any>) => { if (event instanceof HttpResponse) { event = event.clone({body: this.modifyBody(event.body)}); } return event; })); } private modifyBody(body: any) { /* * write your logic to modify the body * */ } }import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse} from '@angular/common/http'; import {Injectable} from '@angular/core'; import {Observable} from 'rxjs'; import {map} from 'rxjs/operators'; @Injectable() export class ResponseInterceptor implements HttpInterceptor { intercept(req: HttpRequest, next: HttpHandler): Observable<HttpEvent<any>> { return next.handle(req).pipe(map((event: HttpEvent<any>) => { if (event instanceof HttpResponse) { event = event.clone({body: this.modifyBody(event.body)}); } return event; })); } private modifyBody(body: any) { /* * write your logic to modify the body * */ } }