Beulah Akindele
Beulah Akindele

Reputation: 649

Cancelling Axios get request in React

I have an Axios get request I'd like to cancel upon an event but it doesn't seem to work.

// user.services.js
searchFAQS(query) {
    const CancelToken = axios.CancelToken;
    const source = CancelToken.source();

    source.cancel('Operation cancelled by user')

    return axios.get(
      authHeader.getApiUrl() + '/api/v1/search_faqs',
      {
        cancelToken: source.token,
        params: {
          query: query
        }
      }
    )
  }


// ClassComponent
  onChangeQuery = (e) => {
    if (e.target.value === "") {
      this.setState({
        fFaq: "",
        query: e.target.value
      })
    } else {
      UserServices.searchFAQS().cancel()
      this.setState({query: e.target.value},
        () => UserServices.searchFAQS(this.state.query)
          .then(resp => {
            this.setState({
              fFaq: resp.data,
              fGroups: resp.data.map(f => f.group).filter((value, index, self) => self.indexOf(value) === index)
            })
          }))
    }
  }

I read the cancellation part for the Axios documentation, which is what led me to the attempt above, but it doesn't seem to be canceling after observing the requests from developer tools.

Upvotes: 0

Views: 1138

Answers (2)

Kalhan.Toress
Kalhan.Toress

Reputation: 21901

searchFAQS(query) {
    const CancelToken = axios.CancelToken;
.....

new CancelToken is creating on every searchFAQS call, so it will not get cancel because everytime it's a new token

change as below

let token = null; // define cancel token outside the search fn, then it will not recreate on every call

searchFAQS(query) {
    if (token !== null) {
        token();
    }
    ...

    const { CancelToken } = axios;
    ...
    return axios.get(
       authHeader.getApiUrl() + '/api/v1/search_faqs',
          {
               cancelToken: new CancelToken(function executor(cancellableFn) {
                   token = cancellableFn;
               }),
               params: {
                   query: query
               }
           }
....

Upvotes: 2

Iago Calazans
Iago Calazans

Reputation: 328

On my understanding you solution should looks like this:

// user.services.js
async searchFAQS(query, source = '') {
    const search = axios.get(
      authHeader.getApiUrl() + '/api/v1/search_faqs',
      {
        cancelToken: source.token,
        params: {
          query: query
        }
      }
    );
    if (source /* change to your needs, actualy it cancels all requests */) {
      source.cancel('Ok, its just canceled!');
    }

    return await search.data;
  }


// ClassComponent

  const CancelToken = axios.CancelToken;
  const source = CancelToken.source();

  onChangeQuery = (e) => {
    if (e.target.value === "") {
      this.setState({
        fFaq: "",
        query: e.target.value
      })
    } else {
      UserServices.searchFAQS("", source)
      this.setState({query: e.target.value},
        () => UserServices.searchFAQS(this.state.query, source)
          .then(resp => {
            this.setState({
              fFaq: resp.data,
              fGroups: resp.data.map(f => f.group).filter((value, index, self) => self.indexOf(value) === index)
            })
          }))
    }
  }

Upvotes: 1

Related Questions