JavaScript

# Cancel Axios API Calls

Suppose we wish to cancel a API call before it completes which may be in the case of a search API or a autocomplete API which we have to call multiple times as the user types characters, but we only need the result of the last API to show the latest data.

We can achieve this with axios v0.15 and above as cancellation support was added in axios from v0.15. Click here to see the official documentation.

We can do this by creating a cancel token using the CancelToken.source factory as shown below:

import axios from 'axios';
const CancelToken = axios.CancelToken;
const source = CancelToken.source();

const searchUsers = async (name) => {
    try{
       const response = await axios.get('/search', { params: {name}, cancelToken: source.token });
       // handle response
       return response.data;
    } catch(error) {
        if (axios.isCancel(error)) {
            console.log('Request canceled', error.message);
        } else {
            // handle error
        }
    }
}

// call API
const searchResults = searchUsers('ab');

// cancel the API (the message parameter is optional)
source.cancel('Operation canceled by the user.');

Now in case of a search API or a Autocomplete API we only require the latest result of the most recent API call and as the user types we can cncel all the previous API calls if they are still in the pending state which will help us optimize our application and reduce data processing.

For this let's implement a generic cancelRequestAxios class which we can plug and play anywhere we want to use the cancel request functionality to cancel the previous API call if a new request is made, For this we need to implement the following:

  1. Keep track of the latest API call by attaching a cancelToken
  2. Functionality to generate cancelToken for every new API call and cancel the previous API call if new API call is made by keeping a refference to it.
  3. Functionality to reset cancalToken refference of the API if the APIis resolved.

Let's implement the same :

import axios from 'axios';

export class cancelRequestAxios {
    constructor() {
      // refference to API call
      this.cancel_resquest = null;
    }

    // Cancel API call if refference is there and create a new cancelToken for new API call 
    cancelAndCreateToken = () => {
        if(this.cancel_resquest){
            this.cancel_resquest.cancel();
        }
        this.cancel_resquest = axios.CancelToken.source();
    }

    // reset Cancel token
    resetCancelToken = () => {
        this.cancel_resquest = null;
    }
}

Let's see how we can use this class:

import axios from 'axios';
import { cancelRequestAxios } from './CancelRequest';

// Create Cancel Request class object
const cancelRequestAxiosObject = new cancelRequestAxios();

export const searchUsers = async (name) => {
    // Canel previous API and create a new cancelToken for the upcoming API call
    cancelRequestAxiosObject.cancelAndCreateToken();
    try{
        const response = await axios.get('/search',{params: {name}, cancelToken: cancelRequestAxiosObject.cancel_resquest.token});
        // On success reset cancelToken
        cancelRequestAxiosObject.resetCancelToken();
        //handle response
        return response.data;
    } catch (error) {
        if (axios.isCancel(error)) {
            console.log('Request canceled', error.message);
        } else {
            // handle error
        }
    }
}

This is a way to cancel previous API calls if we only care about the latest result.



By Ashish Kanwar Singh

Building products that matter
Senior Software Engineer @XanaduAI

Ashish Kanwar Singh's DEV Profile