danielsto
danielsto

Reputation: 134

Is there some way to make recursive fetch requests?

I want my fetch request to have some sort of retry system if it somehows fails based on the HTTP code of the response (for example: not 200). It looks something like this:

fetch('someURLWithAJSONfile/file.json')
        .then(function (res) {
            console.log(res.status);
            if (res.status !== 200) {
                console.log("There was an error processing your fetch request. We are trying again.");

// Recursive call to same fetch request until succeeds

            } else {
                return res.json();
            }
        }).then(function (json) {
        data = json;
    }).catch(function (err) {
        console.log(`There was a problem with the fetch operation: ${err.message}`);
    });

Is there a way to put the fetch request inside a custom Promise and make it call itself after checking its http response status?

Upvotes: 2

Views: 10937

Answers (2)

dhilt
dhilt

Reputation: 20814

Here the simple ES6 solution (since you are using fetch). The limit option means how many times you want to try your request.

var doRecursiveRequest = (url, limit = Number.MAX_VALUE) => 
  fetch(url).then(res => {
    if (res.status !== 200 && --limit) {
      return doRecursiveRequest(url, limit);
    } 
    return res.json();
  });

doRecursiveRequest('someURLWithAJSONfile/file.json', 10)
  .then(data => console.log(data))
  .catch(error => console.log(error));

Upvotes: 5

musicfuel
musicfuel

Reputation: 1680

You can do this by wrapping your call to fetch in a named function that returns the promise created by fetch. Consider:

function fetchWithRetry(url, retryLimit, retryCount) {
    retryLimit = retryLimit || Number.MAX_VALUE;
    retryCount = Math.max(retryCount || 0, 0);
    return fetch(url).then(function (res) {
        console.log(res.status);
        if (res.status !== 200 && retryCount < retryLimit) {
            console.log("There was an error processing your fetch request. We are trying again.");
            return fetchWithRetry(url, retryLimit, retryCount + 1);
        } else {
            return res.json();
        }
    });
}

fetchWithRetry('someURLWithAJSONfile/file.json', 10).then(function (json) {
    data = json;
}).catch(function (err) {
    console.log(`There was a problem with the fetch operation: ${err.message}`);
});

This code wraps your existing call and takes advantage of closure scope to maintain a retry limit and count which are both optional. You then call the fetchWithRetry function with a URL just like you did your previous call to fetch. If you do not pass a retry limit it will continue endlessly. The final retryCount variable is really only used for recursion purposes and is meant to be called internally.

Upvotes: 4

Related Questions