Below the Radar
Below the Radar

Reputation: 7635

XMLHttpRequest - resend data on xhr error

I use an XMLHttpRequest inside a Promise. Because the server sometimes is idle, I would like to do 3 attemps when there is an error.

However, doing like below raise the Object state must be opened error on line xhr.send() in the function sendData(). Why?

I think the xhr is already opened. What would be the proper way to achieve this?

function _callService(url, postData) {
    return new Promise(function(resolve, reject) {
        var xhr = new XMLHttpRequest();
        var attempts = 0;
        xhr.open("POST", url);
        xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        xhr.onreadystatechange = function() {
            if (xhr.readyState == 4 && xhr.status == 200) {
                    resolve(xhr.response);
                }
            }
        };
        xhr.addEventListener("error", onXhrError);

        function sendData() {
           //here I get the Object state must be opened when this is called from onXhrError listener
           xhr.send(postData); 
        };

        function onXhrError() {
            console.log("onXhrError");
            if (attempts < 3) {
                attempts += 1;
                sendData();
            } else {
                reject("OnXhrError")
            }
        };

        sendData();
    });

Upvotes: 0

Views: 1643

Answers (1)

guest271314
guest271314

Reputation: 1

Schedule _callService(url, postData, attempts) to be called again instead of sendData(), see multiple, sequential fetch() Promise.

function callService(attempts) {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      if (attempts < 3) 
        reject(++attempts)
      else 
        resolve("done");
    }, Math.floor(Math.random() * 1200))
  }).catch(function(err) {
    throw err
  })
}

function request(n) {
  return callService(n)
    .then(function(data) {
      console.log(data);
      return data
    })
    .catch(function(err) {
      console.log(err);
      return typeof err === "number" && err < 3 ? request(err) : typeof err !== "number" ? new Error(err) : "requested " + err + " times";
    })
}

request(0)
  .then(function(done) {
    console.log("done:", done)
  })
  .catch(function(err) {
    console.log(err)
  })

Upvotes: 1

Related Questions