0

I'm running a ubuntu server on vagarnt on windows. I have a JSON file on document root in a folder. I want to use async/await to fetch that JSON data. Here is the code I came up with after Googling and learning.

    async function getJSON() {
    try {
      var result = await makeRequest("GET", "./form-data/test-items/test.json");
      console.log(result);
    } catch(error) {
      console.log(error);
    }
  }

  function makeRequest(method, url) {
    return new Promise(function(resolve, reject) {
      let xhr = new XMLHttpRequest();
      xhr.overrideMimeType("application/json");
      xhr.addEventListener("readystatechange", function() {
        if (xhr.readyState === 4 && xhr.status === 200) {
          var respond = xhr.responseText;
          resolve(respond);
        } else {
          reject(xhr.statusText);
        }
      }, false);
      xhr.open(method, url, true);
      xhr.send();
    });
  }

  document.addEventListener("DOMContentLoaded", getJSON, false);

The problem is that only the catch block in the async function has been running. I'm sure I get the respond text from the Ajax request since I have tested it on console. But I don't know how the await statement has been failing.

How can I fix this? And which part have I been missing?

Zaw W. Lwin
  • 85
  • 1
  • 7
  • I would suggest to close it as duplicate to [How do I promisify native XHR?](https://stackoverflow.com/questions/30008114/how-do-i-promisify-native-xhr) (even if the problem is a complelty differnt in the question itself). As that duplicate shows how to properly promisify a `XMLHttpRequest` with detailed explanations, and the already existing answer here explains what is wrong with the given code. – t.niese Feb 07 '19 at 09:35
  • 1
    @t.niese I agree with you as well. I though it's related to async/await but it's just logic error. – Zaw W. Lwin Feb 07 '19 at 09:46

1 Answers1

3

The problem is a simple logic error. Here:

if (xhr.readyState === 4 && xhr.status === 200) {
  var respond = xhr.responseText;
  resolve(respond);
} else {
  reject(xhr.statusText);
}

you reject the promise, if the readystate is not 4 and status not 200. But that's too soon to tell. If you check:

https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/readyState

you'll note that readyState can have 5 different values. None of which indicate an error.

Conclusion, try something like this:

if (xhr.readyState === 4) {
  if (xhr.status === 200) {
    resolve(xhr.responseText);
  }
  else {
    reject(xhr.statusText);
  }
}
Yoshi
  • 54,081
  • 14
  • 89
  • 103
  • 1
    Or use a `load` event instead of a `readystatechange` event – Quentin Feb 07 '19 at 09:40
  • Thank you. This solution works. I have become so muddle headed that I forgot to check the logic of the statement. Guess I need to read up on Web APIs. Thanks again. – Zaw W. Lwin Feb 07 '19 at 09:42
  • @Quentin You'right, though I'm considering following t.niese's suggesting to close this as a duplicate...?! – Yoshi Feb 07 '19 at 09:42
  • @Quentin `load` event works as well. Is there any difference between two? – Zaw W. Lwin Feb 07 '19 at 09:43
  • @ZawW.Lwin — It means you don't need to check for the readyState to reach 4 (but it won't capture errors, so you'll need to deal with them separately). – Quentin Feb 07 '19 at 09:47