▷ Interceptor Angular8 : TUTORIAL | ¡Explicado!

Los interceptors modifican, interceptan,  las (peticiones, servicios, enpoints, o como lo quieras llamar) de el http de tú aplicación.

Es decir en pocas palabras es un puente entre tu aplicación a el servidor y también lo que viene del servidor a tu aplicación.

Desde la versión de  Angular 4.3, se agregó la interfaz HttpInterceptors para permitir nuevas posibilidades en una aplicación Angular 8 y que muchos usuarios ya venían con esto desde angularJs usándola.

También podemos decir como concepto que es una manera sencilla de "manipular" las peticiones  y respuestas http, evitando así ir por cada servicio que realicemos manualmente. Con esto tendríamos un código mas mantenible y los mas limpio posible.

Y ¿por qué? le digo "Los interceptor", esto a que podemos agregar un listado (Array) de interceptor. ¿Cuantos?,  los que tu quieras, pero hay que tener en cuenta que: Angular 8 aplica interceptor en el orden que los vallas insertando. si primero pusiste interceptor A, después B, después C, las solicitudes fluirán en A --> B --> C y las respuesta fluirán  de C --> B --> A.

Esto indica que no se pueden cambiar el orden ni mucho menos eliminar los interceptor mas adelante en el flujo de tu aplicación, si se requiere modificar el comportamiento de un interceptor automáticamente, se tiene que incorporar esta funcionalidad en algunos de los interceptor.

Hay que aclarar algo, No! se debe de confundir los Guards (CanActivate, CanActivateChild, CanDeactivate, CanLoad), con interceptor.
Los Guards se encargan de controlar las rutas de la negación entre paginas de la aplicación.

Recuerda que los interceptors se van a disparar(Ejecutar), por cada petición http que realices a tu servidor, siempre que los hayas registrado.

Dejémonos de tanta teoría y pongamos las manos en el código.

Lo primero es regístralo! y ¿Donde se hace esto? Esto se hace en el modulo raíz de nuestra aplicación, normalmete en "app.module.ts".

Hay que importar los módulos HTTP_INTERCEPTORS HttpClientModule.

import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';

HttpClientModule se debe de insertar en el array de imports:[] y HTTP_INTERCEPTORS en el array de providers: [], todo esto en  @NgModule:

@NgModule({
    imports: [
        CommonModule,
        BrowserModule,
        HttpClientModule,
        AppRoutingModule
    ],
    declarations: [AppComponent],
    providers: [
        { provide: HTTP_INTERCEPTORS, useClass:" --> Aqui se cargar el interceptor <--", multi: true },
    ],
    bootstrap: [AppComponent]
})

Si nos damos cuenta en useClass: nos pide que carguemos el interceptor "en un momento lo creamos", seguidamente nos pide un tercer parámetro la propiedad multi:  esto nos permite agregar más interceptors si lo requerimos y no sobre escribir nuestro interceptor ya creado.

Regresando a la propiedad useClass: ahora vamos a crear el interceptor con el nombre headers.interceptor.ts.

Para este ejemplo vamos a centrarnos únicamente en HttpRequest en donde vamos a modificar el Headers de la petición actualizando el "Content-Type" y poniéndole Authorization de tipo Token.

Partiendo de que podemos crear una clase de tipo servicio y que puede ser inyectada dinámicamente a quien la demande vamos a usar proveedores inyectables de la librería @angular/core con los que realizar la inyección de dependencias.

Una vez creada la clase de tipo servicio vamos a implementar la interfaz “HttpInterceptor
 HttpRequest, HttpHandler, HttpEvent“, } que se encuentran en ‘@angular/common/http’. Seguidamente implementamos el método que ya viene definido en la interfaz llamada “intercep”.

El servicio con los puntos explicados quedaría de la siguiente manera:

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

@Injectable()
export class HeadersInterceptor implements HttpInterceptor {
    constructor() { }

    intercept(request: HttpRequest, next: HttpHandler): Observable> {
        return next.handle(request);
    }
}

Ahora vamos a escribir nuestra lógica que usaremos para este tutorial, la idea general es que tendremos dos variables, una donde guardaremos el  ContentType, en el cual le  diremos que va hacer un envío de tipo JSON y UTF8, además de una pequeña validación que validara un variable de tipo sessionStorage si ya tiene token y si no la cargamos vacía. El ejemplo quedaría de la siguiente manera:

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

@Injectable()
export class HeadersInterceptor implements HttpInterceptor {
    constructor() { }

    intercept(request: HttpRequest, next: HttpHandler): Observable> {
        let ContentType = 'application/json; charset=utf-8';
        let authorization = '';

        if (sessionStorage.getItem('currentUser') !== null) {
            authorization = `Token  ${sessionStorage.getItem('currentUser').replace(/['"]+/g, '')}`;
        }
    }
}

Y por ultimo la inserción de los valores, pero CUIDADO!!,Aun nos falta revisar un tema el método "request", donde se va a poner las variables. La documentación de Angular 8, indica que esta instancia de el método es inmutable, entonces ¿Como le hacemos?.

Hay un método llamado "clone", el cual nos va a ayudar a modificar el HttpRequest, y para finalizar tenemos que retornar este servicio a el siguiente interceptor si la hubiera.

Veamos entonces como quedaría:

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

@Injectable()
export class HeadersInterceptor implements HttpInterceptor {
    constructor() { }

    intercept(request: HttpRequest, next: HttpHandler): Observable> {
        let ContentType = 'application/json; charset=utf-8';
        let authorization = '';

        if (sessionStorage.getItem('currentUser') !== null) {
            authorization = `Token  ${sessionStorage.getItem('currentUser').replace(/['"]+/g, '')}`;
        }

        request = request.clone({
            setHeaders: {
                Authorization: authorization,
                "Content-Type": ContentType,
            }
        });
        return next.handle(request);
    }
}

Listo ya tenemos nuestro servicio de interceptor funcionando ahora solo faltaría agregar la regencia a nuestro modulo.

Veamos como quedaría con los últimos cambios aplicados

import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';

import { HeadersInterceptor} from './headers.interceptor';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

@NgModule({
    imports: [
        CommonModule,
        BrowserModule,
        HttpClientModule,
        AppRoutingModule
    ],
    declarations: [AppComponent],
    providers: [
        { provide: HTTP_INTERCEPTORS, useClass:HeadersInterceptor, multi: true },
    ],
    bootstrap: [AppComponent]
})

¡Y listo!!!, así funcionan los interceptors y recuerda podemos hacer muchas cosas, por ejemplo:

- Mostrar spinners de progreso mientras las llamadas HTTPS están en progreso.
- Validar errores en llamadas HTTP en un solo lugar
- Mensajes de respuesta usando notificaciones.

En pocas palabras, podemos decir que cualquier cosa que sea posible hacer con llamadas HTTP, puede ser lograda por Inceptors.

Para este primer tutorial no tenemos el ejemplo en tiempo real, sino hasta otro post donde explicaremos FAKE BACKEND.

NOTA!!!

No estamos creando una llamada http en este ejemplo, pero si lo usas en tus peticiones ya hechas debe de funcionar perfectamente.

Esperamos le haya gustado, y cualquier duda no te olvides de comentar.

Saludos.....

Elder López Félix

Elder López Félix

Backend Developer | Python / Django - Javascript / AngularJs / Angular - 5

@Elderl23

0 Comentarios

Error message here!

Error message here!

Hide Error message here!

¿Perdiste tu contraseña? Por favor, introduzca su dirección de correo electrónico. Recibirás un enlace para crear una nueva contraseña.

Error message here!

Back to log-in

Close