Interceptores en Angular 4.3+

0
7714

En este tutorial vamos a dar la bienvenida por fin a los interceptores que tanto nos ayudaban en AngularJS y tanto echábamos de menos en Angular.

Índice de contenidos

1. Entorno

Este tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil Mac Book Pro 15″ (2,3 Ghz Intel Core i7, 16 GB DDR3)
  • Sistema Operativo: macOS Sierra
  • @angular 4.3

2. Introducción

Una de las cosas que menos me gustaban de Angular era la forma en la que teníamos que extender de la clase BaseRequestOptions para modificar la petición para, por ejemplo, añadirle el token en la cabecera «Authentication» a todas las peticiones y no tener que hacerlo uno por uno. El método merge me resulta muy confuso y tiene una serie de bugs reportados. Yo decía: «Esto con interceptores en AngularJS era trivial :-(«

Y, por fin, a partir de la versión 4.3 de Angular y la nueva implementación del servicio HttpClient, ya podemos hacer uso de ellos,
entre otras novedades que iré comentando.

3. Vamos al lío

Como comentaba, vamos a resolver el caso de uso de tener que modificar la cabecera «Authentication» para incluir el token de acceso.

Simplemente tenemos que crear una clase que implemente la interfaz HttpInterceptor. Esta implementación requiere de implementar el método intercept, el cual recibe la petición y el siguiente interceptor en la cadena.

Es muy importante que mantengamos la petición inmutable, por lo que cualquier cambio lo haremos en una petición clonada, la cual enviamos al siguiente interceptor de la cadena.

Teniendo esto en cuenta, aplicamos nuestra lógica, que es recuperar el token del servicio de autenticación y establecerlo en el clon de la petición.

import {Injectable} from '@angular/core';
import {HttpEvent, HttpInterceptor, HttpHandler, HttpRequest} from '@angular/common/http';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  
  constructor(private auth: AuthService) {}

  intercept(req: HttpRequest, next: HttpHandler): Observable<HttpEvent> {
    // Obtenemos el token
.    const token = this.auth.getToken();
    // Importante: modificamos de forma inmutable, haciendo el clonado de la petición
    const authReq = req.clone({headers: req.headers.set('Authorization', token)});
    // Pasamos al siguiente interceptor de la cadena la petición modificada
    return next.handle(authReq);
  }
}

Una vez tenemos implementada la clase, es hora de convertirla en provider para que el framework sepa de su existencia y pueda hacer uso de ella.

Para ello vamos al módulo principal (o al secundario que haga uso del servicio HttpClient) y en el array de providers añadimos el interceptor al token de Angular «HTTP_INTERCEPTORS» que, como ves, tiene la propiedad multi a true para aceptar más de un elemento y formar la cadena de interceptores.

import {NgModule} from '@angular/core';
import {HTTP_INTERCEPTORS} from '@angular/common/http';

@NgModule({
  providers: [{
    provide: HTTP_INTERCEPTORS,
    useClass: AuthInterceptor,
    multi: true,
  }],
})
export class AppModule {}

Es importante resaltar que el orden en la declaración de providers va a determinar el orden de la cadena de interceptores.

¡Y ya está! 🙂

4. Conclusiones

De una manera muy mantenible e intuitiva hemos resuelto un caso de uso muy común que de otro modo nos obligaría a implementar mucho código repetitivo. Ya he dicho que esto ya estaba resuelto con la extensión de BaseRequestOptions pero ahora es mucho más intuitivo; lo que demuestra que la gente de Angular mantiene muy vivo el proyecto con importantes mejoras. Ganas tengo de ver qué nos trae la versión 5. 😉

Cualquier duda o sugerencia en la zona de comentarios.

Saludos.

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad