简体   繁体   中英

How do I iterate through an array of JSON objects in Javascript?

Similarly phrased questions have been posed here multiple times, but none seem to help me with my issue. I am working with JSON data pulled from an API (PokeAPI), and I've stored this data in an object in Javascript. As I understand it, this then stores the JSON data in an array, Console.log(myData) yields me the following in the Chrome console:

Console output full data

I want to build a table laying out some of the data in each of these objects in the array. I thought I could access any field in each object by simply using code such as myData[0].name , but this is failing. Attempting to execute Console.log(myData[0]) simply returns an undefined object. How can I access the data I want iteratively?

My current attempt looks as follows:

function getData(inputData) {
var data = [];
    for (i = 0; i < inputData.length; i++) {
        data[i] = [
            inputData[i].id,
            inputData[i].name,
            inputData[i].height,
            inputData[i].weight,
            inputData[i].type[0],
            inputData[i].base_experience];
}

console.log(inputData); //Returns all the data
console.log(inputData[0]); //Returns undefined
return data;

Edit: A couple comments asked to see how I fetched the data from the API. Here it is:

function fetchData(endpoint_URL) {
$.ajax({
    url: base_URL + endpoint_URL,
    dataType: "json",
    success: function (response) {
        //console.log(response);
        let p = new Promise((resolve, reject) => {
            successHandler(response);
            if(dataSet != null) {
                //console.log(dataSet);
                resolve('Success');
            } else {
                reject('Failed');
            }
        })
        
        //console.log(dataSet);
        p.then((message) => {
            //console.log(dataSet);
            loadTableData(dataSet)
        }).catch((message) => {
            console.log("Data fetch unsuccessful");
        })
    },
    error: function(request, status, error){
        console.log(status);
    }
});


function successHandler(response) {
    dataSet = [];
    interimData = [];
        for (var i in response.results) {
            interimData[i] = response.results[i];
            //console.log(response.results[i]);
            //console.log(dataSet[i]);
        }
        //console.log(interimData);

        for (let i = 0; i<interimData.length; i++) {
            $.ajax({
                url: interimData[i].url,
                dataType: "json",
                success: function(details) {
                    dataSet[i] = details;
                }
            })
        };
        //console.log(dataSet);
};

The dataSet object is declared outside of any function (globally?) with the code var dataSet=[]; . The getData() function is called in the first line of loadTableData()

You may be experiencing an issue where your console is showing non-synchronous data ("this value was evaluated just now" message). So this may be related to your operations regarding fetching the data from the API, if so, you may be console.log-ging the object at [0] which at the time of the call is undefined because this function completes its run before the data is actually fetched. The whole object may be console.log-able due to dev console behavior that will evaluate the object at the time you click on it in the console.

Here is a basic call using async and await:

async function getDataAsync () {
  let fetchedData;
  const response = await fetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(response => response.json())
  .then(json => fetchedData = json);
  console.log(fetchedData.userId); // 1
  return fetchedData;
}

var result1 = await getDataAsync();
console.log(JSON.stringify(result1)); // {"userId":1,"id":1,"title":"delectus aut autem","completed":false}

Here is one with nested calls using Promise.all() :

async function getDataWithOtherResultsAsync () {
  let fetchedData;
  const response = await fetch('https://jsonplaceholder.typicode.com/todos/1')
    .then(response => response.json())
    .then(json => fetchedData = json);
  
  const otherUrlsToTry = ['https://jsonplaceholder.typicode.com/todos/2', 'https://jsonplaceholder.typicode.com/todos/3'];
  const otherUrlPromises = otherUrlsToTry.map(m => 
    new Promise(
      resolve =>
      fetch(m)
       .then(n => n.json())
       .then(json => resolve(json))
    )
  );

  const otherUrlResults = await Promise.all(otherUrlPromises);

  return { mainData : fetchedData, otherData : otherUrlResults };
}

var result2 = await getDataWithOtherResultsAsync();
console.log(JSON.stringify(result2));
/*
{
  "mainData":{"userId":1,"id":1,"title":"delectus aut autem","completed":false},
  "otherData":[
    {"userId":1,"id":2,"title":"quis ut nam facilis et officia qui","completed":false},
    {"userId":1,"id":3,"title":"fugiat veniam minus","completed":false}
  ]
}
*/

That's only a side-fact to what Vasily Hall told you.

It looks like you put an Array into an Array:

function getData(inputData) {
   var data = [];
   for (i = 0; i < inputData.length; i++) {
    // data[i] is declared as Array:
    data[i] = [
        inputData[i].id,
        inputData[i].name,
        inputData[i].height,
        inputData[i].weight,
        inputData[i].type[0],
        inputData[i].base_experience];
}

Try this instead:

function getData(inputData) {
var data = [];
for (i = 0; i < inputData.length; i++) {
    // bracelets makes it an object 
    data[i] = {
        inputData[i].id,
        inputData[i].name,
        inputData[i].height,
        inputData[i].weight,
        inputData[i].type[0],
        inputData[i].base_experience};

   // alternative you can use this:
   data.push({...inputData[i]});
  }

console.log(inputData); //Returns all the data
console.log(inputData[0]); //Returns undefined
return data;
}

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