Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Looping API calls with Axios and Promises

I'm using Axios to make API calls, and for one call I'd like to continue polling the API until I get a response.

However, when I call this function something resolves the promise earlier than expected.

I call the function here:

componentDidMount() {
  api.getUser(this.props.user.id)
  .then((response) => {
    console.log(response);
    this.handleSuccess(response.content);
  })
  .catch((error) => {
    this.handleError(error);
  });
}

And the console.log on line 4 shows undefined. The function does continue polling and stops when it receives valid data.

The function itself:

getUser(id, retries = 0) {
  return axios(getRequestConfig)
  .then((res) => {
    if (res.data && res.data.content.status === 200) {
      return Promise.resolve(res.data); // success!
    } else if (retries >= 15) {
      return Promise.reject(res); // failure
    } else {
      // try again after delay
      delay(1000)
      .then(() => {
        return this.getUser(id, retries + 1);
      })
    }
  })
  .catch(err => err);
}
like image 760
Toby Avatar asked Dec 18 '22 07:12

Toby


2 Answers

I'd outsorce the polling logic into a seperate function:

//expects fn() to throw if it failed
//if it runs out of retries, poll() will resolve to an rejected promise, containing the latest error
function poll(fn, retries = Infinity, timeoutBetweenAttempts = 1000){
    return Promise.resolve()
        .then( fn )
        .catch(function retry(err){
            if(retries-- > 0)
                return delay( timeoutBetweenAttempts )
                    .then( fn )
                    .catch( retry );
            throw err;
        });
}



getUser(id) {
    function validate(res){
        if(!res.data || res.data.content.status !== 200) 
            throw res; 
    }
    return poll(() => axios(getRequestConfig).then(validate), 15, 1000);
}
like image 96
Thomas Avatar answered Dec 24 '22 00:12

Thomas


There is a library axios-request-handler that supports polling out of the box.

like image 44
Mike Antoniadis Avatar answered Dec 24 '22 02:12

Mike Antoniadis