0

I am new in javascript and Ajax, would need to retry 3 times if ajax response is not 200.

Ajax Function -

function fireAndForget(strURL) {
    log("will try to invoke... [ " + strURL + " ]");
    var xmlHttpReq = false;
    var self = this;
    // Mozilla/Safari
    if (window.XMLHttpRequest) {
        self.xmlHttpReq = new XMLHttpRequest();
    } // IE
    else if (window.ActiveXObject) {
        self.xmlHttpReq = new ActiveXObject("Msxml2.XMLHTTP");
    }
    self.xmlHttpReq.open('GET', strURL, true);
    self.xmlHttpReq.onreadystatechange = function() {
        if (self.xmlHttpReq.readyState == 4) {
            if(self.xmlHttpReq.status == 200) {
                log("received JSON response : [" + self.xmlHttpReq.responseText + "]");
                var resObj = parseJSON(self.xmlHttpReq.responseText);
                if("handled" in resObj) {
                    if(resObj.handled) {
                        if("success" in resObj) {
                            if(resObj.success) {
                                // DO NOTHING
                            } else {
                                if(resObj.message) {
                                    alert(resObj.message);
                                }
                            }
                        }
                    }
                } else {
                    log("auth update notification was not handled. response : [" + self.xmlHttpReq.responseText + "]");
                }
            } else {
                // unable to contact the auth update listener
                alert("<%=pNotifyFailedMsg%>");
                log("unable to contact listener URL @ [" + strURL + "]");
            }
        }
    };
    // fire a get request with the SSO information
    self.xmlHttpReq.send(null);
    //alert("sent url : [" + strURL +"]");
}

Need to add retry on

if(self.xmlHttpReq.status == 200) {
        log("received JSON response : [" + self.xmlHttpReq.responseText + "]");
        var resObj = parseJSON(self.xmlHttpReq.responseText);
        if("handled" in resObj) {
            if(resObj.handled) {
                if("success" in resObj) {
                    if(resObj.success) {
                        // DO NOTHING
                    } else {
                        if(resObj.message) {
                            alert(resObj.message);
                        }
                    }
                }
            }
        } else {
            log("auth update notification was not handled. response : [" + self.xmlHttpReq.responseText + "]");
        }
    } else {
        // unable to contact the auth update listener
        alert("<%=pNotifyFailedMsg%>");
        log("unable to contact listener URL @ [" + strURL + "]");
    }

I have tried with loop and some other solution in else part of above code, but didn't work, Kindly help. What should be the good approach for retry in such cases

Have to show alert(else part) only after 3 retry

Afgan
  • 892
  • 5
  • 27
  • It would probably be easier to [make a promise of your xhr](https://stackoverflow.com/a/30008115/1641941) then you can simply define a function like so: `const makeRequest = (maxRetries,tries=0) => (args) => xhrPromise().catch((error)=>tries...).catch(error=>...)` – HMR Jan 30 '19 at 08:36
  • Thanks, Could you please elaborate it a bit regarding my scenario , to get more understanding. – Afgan Jan 30 '19 at 08:38

1 Answers1

1

I assume makeRequest is the function described here and if you need classic JS you can translate ES6 like const x = (a,b=0)=>(c)=>22 to function x(a,b){if(b===undefined){b=0} return function(c){...

Your retry builder function could look something like this:

const createRetry = (
  maxRetries, //how many times to try
  passingResults = (id) => id, //function to "pass the result"
  tries = 0, //how many times tried
) => (method, url) =>
  makeRequest(method, url)
    .then(passingResults)
    .catch(
      (error) =>
        tries < maxRetries
          ? createRetry(//call itself again when it failed
              maxRetries,
              tries + 1,//add one to tries as we've just tried
              passingResults,
            )(method, url)
          : Promise.reject(error),//tried max tries times, just reject
    );

const retryTwiceAndNameIsInResponse = createRetry(
  2, //retry twice
  //function to check the xhr json result, if result has a name
  //  property then it passes and just returns the result,
  //  if not then it will reject the promise with an error
  //  a function can be optionally passed, if it's not passed
  //  then it will default to an id function (just returns what it gets)
  (result) =>
    result.name
      ? result
      : Promise.reject(new Error('no name in result')),
  //no need to pass tries in as that defaults to 0 and indicates how
  //  many times the method has tried to get the right result
);

//to use the function:
retryTwiceAndNameIsInResponse(method,url)
.then(response=>console.log('passed, response is:',response))
.catch(error=>console.log('we failed:',error))
HMR
  • 30,349
  • 16
  • 67
  • 136