Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to separate XMLHttpRequest from the main function for better visbility/testibility (without Promises / asnyc/await )

Imagine this function:

function myMainFunction() {
  doSomeInitialStuff();
  // more stuff..
  var xhr = new XMLHttpRequest();
  xhr.onreadystatechange = function () {
    if (xhr.readyState == XMLHttpRequest.DONE) {
      // Now that we know we received the result, we can do the heavy lifting here
      if (xhr.status == 200) {
        console.log("ready 200");
        let result = JSON.parse(xhr.responseText);
        doStuff(result);
        // and much more stuff..
      } else {
        console.log("error", xhr.status);
        return undefined;
      }
    }
  };

  xhr.open("GET", "http://example.com", true);
  xhr.send(null);
}

This works fine, but it is impossible to test, and this function has become a monster.
So I’d like to refactor it, by separating all the different parts in their own unique functions.
The problem is, I do not know how to extract the XHR part and still keep it working.
I cannot use Promises nor asnyc/await and have to stick to using plain XHR.
What I’d normally do is to create a seperate async function for the ajax call (or the xhr in this case). Simply await it’s result and go from there. Easy to separate. But I do not have the luxury of await or anything this time.

What I am trying to get at is something like this

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

function refactoredMyMainFunction() {
  doSomeInitialStuff();
  // more stuff..
  let result = xhrFunction(); 
  doStuff(result); // result would be undefined here, since I cannot wait for the xhr request to finish. 

}

>Solution :

You can implement a callback-based API:

function myMainFunction() {
  doSomeInitialStuff();
  // more stuff..
  xhrFunction(doStuff);
}

function xhrFunction(cb) { 
  var xhr = new XMLHttpRequest();
  xhr.onreadystatechange = function () {
    if (xhr.readyState == XMLHttpRequest.DONE) {
      // Now that we know we received the result, we can do the heavy lifting here
      if (xhr.status == 200) {
        console.log("ready 200");
        let result = JSON.parse(xhr.responseText);
        cb(result);
        // and much more stuff..
      } else {
        console.log("error", xhr.status);
        return undefined;
      }
    }
  };

  xhr.open("GET", "http://example.com", true);
  xhr.send(null);
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading