How to Loop HTTP Requests Until Some Condition Is Met


I recently ran into an issue where I needed to keep sending HTTP requests until I had some valid response.

“Valid” means something different in different contexts.

Sometimes “valid” is just when status === 200, but other times, it’s something completely different.

I needed to fetch data from an API, but it was returning inconsistent responses.

Let’s say, for this example, our data (res.data) returns some JSON object that looks like this:

{
    results: []
}

I wanted to keep making requests until results was populated.

This is what I did.

const sendRequest = async (query) => {
  const options = {
    url: `${API_URL}?q=${query}`, // Some valid API URL
    method: "GET" // Perform GET request
  };
  return new Promise((resolve, reject) => {
    const request = (retries) => {
      // Make the HTTP request
      axios(options).then((res) => {
          // Check some condition based on response
          // Check number of retries left
          if (res.data.results.length > 0 && retries > 0) {
            request(--retries);
          } else {
            return resolve(res.data);
          }
      }).catch((error) => {
          reject(error);
      });
    };
    request(5);
  });
};

I wrapped my axios request inside a request() method, which takes in the number of retries I have for the current call.

When the axios callback gains program control, I check that res.data.results is populated and that I have some retries left.

If res.data.results is empty or I’ve used all my attempts, then I just resolve with the JSON object.

At the bottom, I called request(5), giving myself five attempts to retrieve desirable results.