javascript - example - httpclient angular 6
Angular 4.3 HttpClient: respuesta de intercepciĆ³n (4)
En la documentación sobre el nuevo
HttpClientModule
incluido en la nueva versión de Angular 4.3, el mecanismo para interceptar solicitudes se explica muy bien.
También se menciona el mecanismo interceptor de respuesta, sin embargo, no puedo encontrar nada al respecto.
¿Alguien tiene una idea sobre cómo interceptar una respuesta para modificar el mensaje del cuerpo antes de enviarlo al servicio?
Gracias.
Con la versión Angular 6, han adaptado RxJs 6.0 debido a que la mayoría de las soluciones anteriores no funcionarán en esta versión particular de angular, así es como se modifica correctamente el contenido de un Observable
import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse} from ''@angular/common/http'';
import {Observable} from ''rxjs/internal/Observable'';
import {Injectable} from ''@angular/core'';
import {tap} from ''rxjs/operators'';
@Injectable()
export class ResponseInterceptor implements HttpInterceptor {
intercept(req: HttpRequest, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).pipe(tap((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
* */
}
}
Por lo que puedo entender (solo he hecho la intercepción para solicitar e inyectar token de autenticación) ... puede adjuntar un .do () y probar si es una respuesta ... como (como dice el documento):
import ''rxjs/add/operator/do'';
export class TimingInterceptor implements HttpInterceptor {
constructor(private auth: AuthService) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const started = Date.now();
return next
.handle(req)
.do(event => {
if (event instanceof HttpResponse) { //<-- HERE
const elapsed = Date.now() - started;
console.log(event} ms.`);
}
});
}
}
Recientemente hice 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.
(Esta es la salida 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 las necesidades de OP. Para hacerlo, es necesario 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 se pasa al siguiente controlador.
Supongo que puedes usar
do
como sugirió @ federico-scamuzzi, o puedes 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)
.
Yo uso
guardias de ruta
, 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 argumento a mi ruta:
{
path: ''dashboard'', loadChildren:''app/dashboard/dashboard.module#DashboardModule'',
canActivate: [AuthGuard]
}