'Cancel async request on unmount with axios
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.
Solution 1:[1]
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>
)
}
}
Solution 2:[2]
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;
Solution 3:[3]
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))
);
Solution 4:[4]
use faxios instead of axios
let req = faxios()
.url('abc/xyz')
.GET
.then(res => {})
.catch(err => {});
// canceling...
req.cancel();
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | |
| Solution 3 | Ravindra Ranwala |
| Solution 4 | challenger |
