Interceptors are a very fun concept in axios, and they can permit you to intercept and modify requests before being sent to the server. It can be used for scenarios such as requesting new tokens or showing error messages when a request fails. In this article, we will see what interceptors are in axios and how to create a small snippet to handle interceptors in React Native.

What are interceptors in axios?

Interceptors are built mechanisms in axios that permit you to modify the request or the responses of HTTP requests. They permit you to handle your application state better. Being a native feature in axios, interceptors can be instantiated from the general axios config.

Types of interceptors

There exist two types of interceptors in axios: request and response interceptors.

Request interceptor

The request interceptor is used to intercept all requests sent by the users; you can use it to modify the outgoing request, such as adding an access token to the request header. We can see an example of the interceptor below

// Add a request interceptor
axios.interceptors.request.use(function (config) {
    // Do something before request is sent
    return config;
  }, function (error) {
    // Do something with request error
    return Promise.reject(error);
  });

The config passed in the callbacks contains parameters from requests, such as the headers, URL, request parameters, and request type. Changing config parameters take effect in the request, and it’s important always to return the request.

Response interceptor

The response interceptor is used to handle the responses from axios requests. The response has a call back as in the request interceptor, which gives you the response details before it is sent back to the user. You can use it to check specific error codes and display custom notification errors.

// Add a response interceptor
axios.interceptors.response.use(function (response) {
    // Any status code that lie within the range of 2xx cause this function to trigger
    // Do something with response data
    return response;
  }, function (error) {
    // Any status codes that falls outside the range of 2xx cause this function to trigger
    // Do something with response error
    return Promise.reject(error);
  });

Adding axios interceptors in React Native

After seeing the different interceptors and how they work, we will see how we can add axios in our React Native project, and we will write HOC to intercept all axios requests. We shall start by installing axios by running the following command.

npm i axios

Now we will create our HOC to handle all axios requests; in the snippet below, we add the access token when doing requests and also handle all response errors.

Ps: in a normal scenario, I use a toast to display errors when the request fails.

import { AUTH_BASE_URL } from '../config/constants';


import { RootState } from '../store/configStore';

import axios, { AxiosError, AxiosRequestConfig, AxiosPromise } from 'axios';
import { Store } from 'redux';


axios.defaults.baseURL = AUTH_BASE_URL;

export type InterceptorCallback = (
  store: Store,
  api: AxiosRequest,
) => Promise<unknown> | unknown;

export interface ConfigAxios extends AxiosRequestConfig {
  __isRetryRequest?: boolean;
  __override?: boolean;
}

export interface InterceptorError extends AxiosError {
  config: ConfigAxios;
}

export type AxiosRequest = (options: ConfigAxios) => AxiosPromise;


export const requestInterceptor = (store: Store) => {
 // get values from store
  const { auth } = store.getState();

  return axios.interceptors.request.use(async (config: ConfigAxios) => {

    config!.headers!.Authorization = `Bearer ${auth?.user?.accessToken}`;

    return config;
  });
};



export const errorInterceptor = (
  code: number | string,
  store: Store,
  callback: InterceptorCallback,
  api: AxiosRequest,
) => {
  axios.interceptors.response.use(
    undefined,
    async (error: InterceptorError) => {
    
      // you can check if the reponse match a certain url and display a certain error
      if (error.response?.config.url === '') {
     
        // display toasts
      }
      
      // return toasts
      return Promise.reject(error);

  );
};

export const configureInterceptors = async (store: Store<RootState>) => {
  errorInterceptor('*', store, refreshToken, axios);
  requestInterceptor(store);
};

In the example, we used redux to get the values such as access and refresh tokens. Now that we have our snippet working, we will create or HOC, for that create a file called interceptorProvider add and the following code.

import { configureInterceptors } from '@KwSrc/services/interceptor';
import { ReactElement, useEffect } from 'react';
import { Store } from 'redux';

interface InterceptorInterface {
  children: ReactElement;
  store: Store;
}

// This provider is used to provide the interceptos with default auth values

function InterceptorProvider(props: InterceptorInterface) {
  useEffect(() => {
    configureInterceptors(props.store);
  });

  return props.children;
}
export default InterceptorProvider;

Now you will need to wrap your application with the interceptorProvider, for that add it in your application as follows.


import InterceptorProvider from '.../interceptorProvider';


const App = () => (
        <InterceptorProvider store={store}>
              <>
                // your application config goes here
              </>
        </InterceptorProvider>
    );
export default App;

It’s important to note that you will need to modify the snippets above for it to work in your application smoothly

Conculsion

In the article we saw how to use axios interceptors in react native, and we also saw how we can include them with some little snippets on how we can include them in React Native.

lewatt23

Mobile / Web developer

Stanly is a web and mobile developer passionate about creating engaging and user-friendly digital experiences. he has 4+ years building web and mobile applications.

Need help in your next project ?