Better Http request with interceptors in Angular 8 and beyond
Tags: angular, webdev
Published: 2019-11-14 15:27:48

Originally posted on [my blog](https://www.ibrahima-ndaw.com/blog/set-http-interceptor-in-angular/) <hr>
Dealing with API based token is sometimes cumbersome. Due to the fact that, on every request, we have to send a token as parameter to be able to reach out the server.<br>
In Angular, it becomes easier with the help of HttpClient interceptors. In this tutorial, I will lead on how to set up a token once and use it on every request with interceptors.

  - [Prerequisite](#prerequisite)
  - [Interceptors](#interceptors)
  - [Conclusion](#conclusion)

## Prerequisite
Set up a new angular app
```bash
ng new my-app
```
Then add a service file that will handle the logic of sending the request.
```shell
ng generate service data
```
After successfully generated the service add the following lines to send the request to the server.
```javascript
import { Injectable } from "@angular/core";
import { HttpClient, HttpParams } from "@angular/common/http";

@Injectable({
  providedIn: "root"
})
export class DataService {
  constructor(private http: HttpClient) {}

  getData() {
    return this.http.get("https://example.com/api/data", {
      params: new HttpParams().set(
        "auth-token",
        "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9"
      )
    });
  }

  getUsers() {
    return this.http.get("https://example.com/api/users", {
      params: new HttpParams().set(
        "auth-token",
        "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9"
      )
    });
  }
}

```
And in your `app.component.ts` call the service we've created to achieve the request.
```javascript
import { Component } from "@angular/core";

import { DataService } from "./data.service";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.scss"]
})
export class AppComponent {
  constructor(private dataService: DataService) {}

  showData() {
    this.dataService.getData().subscribe(response => {
      // Write your logic here to handle the data
      console.log(response);
    });
  }

  showUsers() {
    this.dataService.getUsers().subscribe(response => {
      // Write your logic here to handle the data
      console.log(response);
    });
  }
}
```
As you can see in the `data.sevice.ts` file, we use the same `params` for both getData() and getUsers() methods to send the token.<br>
Now it's time to optimize it with interceptors.

## Interceptors
Http Interceptors were introduced with version 4.3 of Angular. They help a lot with handling request with the same parameters or headers.<br>
To implement it, we need to create a new file `auth.interceptor.ts`. You can name it whatever you like, but it's a convention to add .interceptor to be clear about what's inside the class file. Next, add this following code block to the file.
```javascript
import {
  HttpInterceptor,
  HttpRequest,
  HttpHandler,
  HttpEvent
} from "@angular/common/http";
import { Observable } from "rxjs";

export class AuthInterceptor implements HttpInterceptor {
  intercept(
    req: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    const cloneReq = req.clone({
      params: req.params.set(
        "auth-token",
        "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9"
      )
    });
    return next.handle(cloneReq);
  }
}
```
First, we need to import `HttpInterceptor` and implement it to our class to be able to access to the `intercept()` method. Then, we pass two arguments req and next to that method. The first is the request of type `HttpRequest` and can have any type of data, and the second `next` will handle the request and let it continue its journey.<br>
The intercept() method is of type `Observable` and can receive any type of events.<br>
The Http request is by default immutable, we can't edit it. Therefore, we need to create a copy by cloning the request with `req.clone()`. Now with this method, we can configure our params directly and return the `cloneReq` request and let it continue its way to the server.<br>
Now, our interceptor will add the token as a parameter on every request before letting it reach out the server. We can even simplify our `data.service.ts` file by removing everything related to params.

```javascript
import { Injectable } from "@angular/core";
import { HttpClient } from "@angular/common/http";

@Injectable({
  providedIn: "root"
})
export class DataService {
  constructor(private http: HttpClient) {}

  getData() {
    return this.http.get("https://example.com/api/data");
  }

  getUsers() {
    return this.http.get("https://example.com/api/users");
  }
}
```
## Conclusion
Http interceptors are useful on every matter. It's kind like middleware in back-end development. We can use it to modify our requests and also our responses.

| [TWITTER](https://twitter.com/ibrahima92_) | [BLOG](https://www.ibrahima-ndaw.com/) | [NEWSLETTER](https://ibrahima-ndaw.us5.list-manage.com/subscribe?u=8dedf5d07c7326802dd81a866&id=5d7bcd5b75) | [GITHUB](https://github.com/ibrahima92) | [LINKEDIN](https://www.linkedin.com/in/ibrahima-ndaw/) | [CODEPEN](https://codepen.io/ibrahima92) | [DEV](https://dev.to/ibrahima92) |
| -------------- | ------------------------------------------ | ----------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ----------------------------- | ------------------------------------------------------ | ---------------------------------------- | -------------------------------- |