简体   繁体   中英

Accessing data returned by ajax request on load

I've been working on a single page site in which data from a single json file is rendered variously in different sections - nothing displayed on load, but only upon click event. I learned a little about callbacks getting that wired up, but as I almost completed it I realized how flawed the concept was, so now I'm back to the drawing board.

My idea now is to make the ajax call onload, set the json result as a variable available to several functions. I thought it would go something like this:

window.onload = function() {

    var myJsonData = function() {
        var request = new XMLHttpRequest();
        request.open("GET", "/json/someJsonData.json", true);
        request.setRequestHeader("content-type", "application/json");
        request.send(null);
        request.onreadystatechange = function() {
            if (request.readyState === 4) {
                if (request.status === 200) {
                    var myJsonString = JSON.parse(request.responseText);
                    var myJsonArray = myJsonString["Projects"];
                    return myJsonArray;
                }
            }
        } // onreadystatechange
    } // var myJsonData

    myJsonData(); // *
    console.log("myJsonArray: " + myJsonArray); // undefined

Or:

window.onload = function() {
    myJsonData();
}

function myJsonData() {
    var request = new XMLHttpRequest();
    request.open("GET", "/json/someJsonData.json", true);
    request.setRequestHeader("content-type", "application/json");
    request.send(null);
    request.onreadystatechange = function() {
        if (request.readyState === 4) {
            if (request.status === 200) {
                var myJsonString = JSON.parse(request.responseText);
                var myJsonArray = myJsonString["Projects"];
                alert("you are here (myJsonArray defined)");
                alert("myJsonArray: " + myJsonArray);
                console.log("myJsonArray: " + myJsonArray);
                return myJsonArray;
            }
        }
    } // onreadystatechange
} // var myJsonData

console.log("myJsonArray: " + myJsonArray); // undefined

Or:

window.onload = myJsonData;
// etc.

Of course myJsonArray is undefined either way. I'm obviously missing something fundamental about how to do this (or is this even a bad idea altogether?). Is there some way to pass a result as a callback when invoking an ajax request on load?

Can someone please enlighten me as to how to proceed from here, a skeletal example perhaps ? (ps still focusing on native js, not jQuery)

Many thanks in advance,

svs

There are some things wrong in the code. First the myJsonArray is local to the function myJsonData(). You have to define it globally. Second, the ajax request is async. You have to wait for the result before working with it. Here is a working example based on your code:

   var myJsonArray;  //Globally defined
        window.onload = function() {

            var outputData = function() {
                console.log(myJsonArray);
            }

            var myJsonData = function() {
                var request = new XMLHttpRequest();
                request.open("GET", "someJsonData.json", true);
                request.send(null);
                request.onreadystatechange = function() {
                    if (request.readyState === 4) {
                        if (request.status === 200) {

                            myJsonArray = JSON.parse(request.responseText);
                            outputData(); //Ouput when result is received
                        }
                    }

                } // onreadystatechange


            } // var myJsonData

            myJsonData(); // *

        }

Using Javascript promises could solve your problem here. Promises are native to ES6 , although obviously the browser support isn't quite fully there yet. Regardless, here is how you could implement your code with promises:

window.onload = function () {
  myJsonData().then(function (result) {
      console.log("myJsonArray: " + result);
      alert(result.one);
      // do something else here
  });
}

function myJsonData() {
  return new Promise(function (resolve, reject) {
      var request = new XMLHttpRequest();
      request.open("GET", "http://echo.jsontest.com/key/value/one/two", true);
      request.setRequestHeader("content-type", "application/json");
      request.send(null);
      request.onreadystatechange = function() {
          if (request.readyState === 4) {
              if (request.status === 200) {
                  var myJsonString = JSON.parse(request.responseText);
                  //var myJsonArray = myJsonString["Projects"];
                  resolve(myJsonString);
              }
          }
      } // onreadystatechange
  });
} // var myJsonData

Here is a jsfiddle

From my experience and understanding.

When you are dealing with sync function and async function, always it is important to know which functions require data from the async callback function.

If the functions fully depend on the data received, it will a good coding practice to call these function in the loop

if (request.readyState === 4) {
    if (request.status === 200) {
        var myJsonString = JSON.parse(request.responseText);
        // call the function which depend on the data received here.
    }
}

I wouldn't recommend setting the async as false as it would just result in page freeze sometimes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM