0

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();
    });
Below the Radar
  • 7,321
  • 11
  • 63
  • 142

1 Answers1

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)
  })
guest271314
  • 1
  • 15
  • 104
  • 177
  • is an xhr state is always DONE when there is an error? – Below the Radar Oct 27 '17 at 17:35
  • See _"done DONE (numeric value 4) The data transfer has been completed or something went wrong during the transfer (e.g. infinite redirects)."_ https://xhr.spec.whatwg.org/#states, http://jsfiddle.net/uxae61c8/ – guest271314 Oct 27 '17 at 17:46