7

I have multiple component with axios plugin for some get requests. i need some help to cancel all xhr request with axios on component unmount event in react js. but the axios cancel code is not working. its return me cancel() is not a function error.

Code example:-

import axios from 'axios'; var CancelToken = axios.CancelToken; var cancel; axios.get('abc/xyz', { cancelToken: new CancelToken(function executor(c) { // An executor function receives a cancel function as a parameter cancel = c; }) }); // cancel the request cancel(); 

Please help me to implement cancel request in axios.

Thanks.

4 Answers 4

6

It is quite simple. Create the request in componentDidMount and cancel it in componentWillUnmount. Replace the url with an existing JSON file and this snippet will work as expected:

class MyComponent extends Component { constructor (props) { super(props) this.state = { data: [] } } componentDidMount () { this.axiosCancelSource = axios.CancelToken.source() axios .get('data.json', { cancelToken: this.axiosCancelSource.token }) .then(response => { this.setState({ data: response.data.posts }) }) .catch(err => console.log(err)) } componentWillUnmount () { this.axiosCancelSource.cancel('Axios request canceled.') } render () { const { data } = this.state return ( <div> {data.items.map((item, i) => { return <div>{item.name}</div> })} </div> ) } }

Sign up to request clarification or add additional context in comments.

Comments

3

In addition to the @taseenb response, if you use react hooks, here's an example.

Use the useEffect to detect route changes. Then, cancel the requests with the AXIOS CANCEL TOKEN when the route is unmounted. After thtat, generate a new AXIOS CANCEL TOKEN to make a new request. See the Axios Doc to more details (https://github.com/axios/axios).

Route.tsx file

import React, { useEffect } from 'react'; import { Route, RouteProps, useLocation } from 'react-router-dom'; import API from 'src/services/service'; const CustomRoute = (props: RouteProps) => { const location = useLocation(); // Detect Route Change useEffect(() => { handleRouteChange(); return () => { handleRouteComponentUnmount(); }; }, [location?.pathname]); function handleRouteChange() { // ... } function handleRouteComponentUnmount() { API.finishPendingRequests('RouteChange'); } return <Route {...props} />; }; export default CustomRoute; 

Service.ts file

import { Response } from 'src/models/request'; import axios, {AxiosInstance, AxiosResponse } from 'axios'; const ORIGIN_URL = 'https://myserver.com' const BASE_URL = ORIGIN_URL + '/api'; let CANCEL_TOKEN_SOURCE = axios.CancelToken.source(); function generateNewCancelTokenSource() { CANCEL_TOKEN_SOURCE = axios.CancelToken.source(); } export const axiosInstance: AxiosInstance = axios.create({ baseURL: BASE_URL, }); const API = { get<DataResponseType = any>( endpoint: string, ): Promise<AxiosResponse<Response<DataResponseType>>> { return axiosInstance.get<Response<DataResponseType>>(endpoint, { cancelToken: CANCEL_TOKEN_SOURCE.token, }); }, // ...Other Functions finishPendingRequests(cancellationReason: string) { CANCEL_TOKEN_SOURCE.cancel(cancellationReason); generateNewCancelTokenSource(); }, }; export default API; 

Comments

1

You can't cancel a request unless you use RxJS. I suggest you use redux-observable for this purpose. Check this for further information. You have to use takeUntil operator in your Epic and do the cancellation when a cancel action fires. Here's the sample code given by the above resource.

import { ajax } from 'rxjs/observable/dom/ajax'; const fetchUserEpic = action$ => action$.ofType(FETCH_USER) .mergeMap(action => ajax.getJSON(`/api/users/${action.payload}`) .map(response => fetchUserFulfilled(response)) .takeUntil(action$.ofType(FETCH_USER_CANCELLED)) ); 

3 Comments

Is this code(redux-observable) woking or relate with promises and component structure ?
It uses RxJS Observables, which is a stream of events created from your response. Then you have to create a subscription to the Observable to get the results. It also gives nice composing api with lots of operators such as map, flatmap, zip etc. It is a different paradigm than ES6 fetch and promise based approach. This more composable approach.
can you refer me some idea without using redux or server. actually i create an very small level appliaction that have 2 or 3 components that are change with routes. i have to cancel my all api request on unmount() in react js lifecycle.
0

use faxios instead of axios

 let req = faxios() .url('abc/xyz') .GET .then(res => {}) .catch(err => {}); // canceling... req.cancel(); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.