Axios Interceptors in React
Tags: react, axios, webdev, programming
Published: 2023-08-07 19:55:41

## INTRO
`Axios` is one of the famous library in React for api calls. I hope you people already know how to do basic api calls using Axios. Today we are discussing about axios interceptors `request` and `response`. The `request interceptor` will helps you to set up (config) something before api call as well as the `response interceptor` will helps you to set up (config) something after api call.

## USAGE
We all know that axios used for api calls. These interceptors will helps us to config the api's before and after every api call. 

`For Example` If you take one project, the base url of that project is same for every api. So we need not to add every time that base url to end points whenever we call the api. Instead we can set up that base url in axios request interceptor. As well as we have to send token as payload, every time we call protected api calls. Instead we can set up that token in axios request interceptor. There are many benefits of using Axios interceptors. Today we will discuss all those configurations.

## CODE
**First we have to create axios instance.**
```javascript
//Axios libray
import axios from 'axios';
//A querystring parsing and stringifying library
import qs from 'qs';
//Base URL from .env
const {REACT_APP_SERVER_URL} = process.env

const instance = axios.create({
  //Base URL of entire project
  baseURL: `${REACT_APP_SERVER_URL}`,
  //Helps to seralize params i.e stringify params
  paramsSerializer(params) {
    return qs.stringify(params, { indices: false });
  },
});
```
**Next we have to create axios request interceptor.**
```javascript
//import package.json from local app
import packageJson from "./package.json";

instance.interceptors.request.use(
  (config) => {
    //import token from local storage
    let token=localStorage.getItem('token') || '';
    //configuring header
    config.headers = {
      Accept: 'application/json',
      'Content-Type': 'application/json',
      Authorization: `Bearer ${token}`, //based on your project requirement
      //or
      "x-token" : JSON.parse(token), //based on your project requirement
      params:{*params*},  //based on your project requirement
      version: packageJson.version, //based on your project requirement
     //other optional headers like Accept-Encoding, Accept-Language or any custom key values like project details.
    };

    return config;
  },
  (error) => Promise.reject(error),
);
```

**Next we have to create axios response interceptor.**
```javascript
import { createBrowserHistory } from 'history';

const history = createBrowserHistory();

instance.interceptors.response.use(
  (response) => {
    //success status
    if (response.status === 200) {
      return response;
    } 
    //error status
    else {  
      const messages = response.data.messages
      if (messages) {
        if (messages instanceof Array) {
          return Promise.reject({ messages });
        }
        return Promise.reject({ messages: [messages] });
      }
      return Promise.reject({ messages: ["got errors"] });
    }
  },
  (error) => {
    //unauthorised error
    if (error.response && error.response.status === 401) {
      localStorage.removeItem("token");
      history.replace({ pathname: "/error" });
    } 
   //internal server error
   else if (error.response && error.response.status === 500) {
      return Promise.reject(error.response);
    } 
   //any other error
  else return Promise.reject(error);
  }
);
```
**The overall code.**

```javascript
//instance.js

import axios from "axios";
import qs from "qs";
import { createBrowserHistory } from "history";
import packageJson from "./package.json";
const { REACT_APP_SERVER_URL } = process.env;

const history = createBrowserHistory();

const instance = axios.create({
  baseURL: `${REACT_APP_SERVER_URL}`,
  paramsSerializer(params) {
    return qs.stringify(params, { indices: false });
  },
});

instance.interceptors.request.use(
  (config) => {
    let token = localStorage.getItem("token") || "";
    config.headers = {
      Accept: "application/json",
      "Content-Type": "application/json",
      "x-token" : JSON.parse(token),
    };

    return config;
  },
  (error) => Promise.reject(error)
);

instance.interceptors.response.use(
  (response) => {
    if (response.status === 200) {
      return response;
    } else {
      if (messages) {
        if (messages instanceof Array) {
          return Promise.reject({ messages });
        }
        return Promise.reject({ messages: [messages] });
      }
      return Promise.reject({ messages: ["got errors"] });
    }
  },
  (error) => {
    if (error.response && error.response.status === 401) {
      localStorage.removeItem("token");
      history.replace({ pathname: "/error" });
    } else if (error.response && error.response.status === 500) {
      return Promise.reject(error.response);
    } else return Promise.reject(error);
  }
);

export const http = instance;

export default http;
```

## CONCLUSION
We can use above `http` function for api calls directly like `http.get` or `http.post` same as `axios.get` or `axios.post` etc.. We can see how to do custom api calls using http function in next post.