简体   繁体   中英

Get array from external Json

I have an external json file file.json and I am trying to get an array stored inside of it so I can use it as a Javascript array. The JSON File:

{
    "data": [
        {
            "Name": "Steve",
            "Number": "120",
            "Number2": "78",
            "Number3": "75",
            "Number3": "85"
        },
        {
            "Name": "Bob",
            "Number": "130",
            "Number2": "98",
            "Number3": "85",
            "Number3": "85"
        },
        {
            "Name": "Joe",
            "Number": "430",
            "Number2": "88",
            "Number3": "75",
            "Number3": "89"
        }
    ]
}

There is an array after the "data": and I would like to use that as an array. This is what I have tried: (just to test)

$.getJSON( "file.json", function( json ) {
    for (var i = 0; i < json.data.length; i++) {
        var Test = json.data[i]; 
        console.log(Test.Name);
    }
});
alert(Test.Name);

Although it didn't return an array, the alert didn't work either. Is there a reason for this? And, if I could get variables or Objects outside the function, how can I create an array and get it outside? Thanks!

$.getJSON() is initiated at the same time as your alert() , but the callback function ( function( json ) ) is not called until the data has been fetched and loaded.

So when you ask for alert(Test.Name) there is no Test.Name to alert! That hasn't been processed yet.

var Test = []
$.getJSON( "file.json", function( json ) {
   for (var i = 0; i < json.data.length; i++) {
      Test = json.data[i]; 
      console.log(Test.Name);
      alert(Test.Name);
   }
});

You won't be able to access Test outside the function as it is defined within. Defining it in the scope outside the function will allow it to be accessed, but until the JSON callback is complete it will be an empty array.

// Define it where you want it to be accessible
var people;

$.getJSON("file.json", function (json) {
    // Store the data in people to make it accessible globally
    people = json.data;
    people.forEach(function(person){ console.log(person.Name); });
    doSomethingElse();
});

// Would cause an error, you didn't receive the data yet
alert(people[0].Name); // Uncaught TypeError: Cannot read property '0' of undefined

// Would work if it is called after receiving the data (inside the callback or later)
function doSomethingElse(){
    alert(people[0].Name); // 'Steve'
}

This is due to the async operation of $.getJSON . Essentially what happens is the JS engine works through your program where it encounters the statement for $.getJSON , executes it (which then awaits a response in the event loop) and continues on to the next statement which is the alert . Since the event loop has not gone around to see if there has been a response yet the value for Test.name is undefined (which actually should have thrown an error unless you declared Test somewhere outside of the $.getJSON response handler).

For example:

 var foo; // using setTimeout as a proxy async operation for $.getJSON setTimeout(function() { foo = 'FOO'; console.log('Inside the async operation', foo); }, 0); // Approximate running in next loop of the event cycle console.log('Outside the async operation', foo); 

What do you think the output will be? Run it and check your console output or just look here:

> Outside the async operation undefined
> Inside the async operation FOO

So how do you get the value for the rest of your code without embedding it within the response function? The two main ways are either to use a callback function (similar to Node's preferred style) or to use promises.

If you didn't notice you are already using a callback function. That is what the function you are passing to $.getJSON is referred to as. So you could add more code to that function or factor it out to another function that is called from the existing response handler.

 setTimeout(function() { var foo = 'FOO'; console.log('Inside the async operation', foo); myOtherCode(foo); }, 0); // Approximate running in next loop of the event cycle function myOtherCode(foo) { console.log('Outside the async operation', foo); } 

Or you could use promises. Since the native JS implementation of Promise is relatively new a lot of libraries exist that allow you to use them on older browsers as well as including extra functionality.

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