简体   繁体   中英

array.push not working with nested JSON objects

I'm trying to do a couple of things:

  1. Take JSON data and push it into an array named 'houses'.
  2. Access data nested within 'houses', and push it into new array named 'values' (I'll later use 'values' in a d3 visualisation).

my JSON is formatted like this:

    [
      {
        "devices": [
          {
            "device_mac": "0c2a690462c6",
            "device_type": "kettle",
            "values": [
              {
                "the_time": "2014-09-22 16:57:19",
                "is_active": "1"
              },
              {
                "the_time": "2014-10-08 07:05:52",
                "is_active": "0"
              },
              {
            "the_time": "2014-09-27 15:53:10",
            "is_active": "1"
          }
        ]
      },
      {
        "device_mac": "0c2a6900446d",
        "device_type": "fridge",
        "values": [
          { [...]

...and so on. Basically there are a series of houses that have a series of devices which have a series of properties and events attached to them.

Currently, I'm just trying to get into the values of a device and push them into an array. This is my current code (which includes comments and functions to help me debug.

var houses = [];
var values = [];

window.onload = function () {
    getData();
    plotData();
    test();
};

function getData() {
    $.getJSON("http://dev.modusdeus.com/f_fridge/all_events.php", function (data) {
        houses.push(data);
        console.log(data[0].devices.device_type);
        console.log("getData has run");
    });
};

function plotData() {

    for (houseIndex in houses) { // what house are we looking at?
        var house = [];
        house = houses[houseIndex];

        for (devicesIndex in house) { //  what devices are we looking at?
            var devices = [];
            devices = house[devicesIndex]; // device's'Index - beware of the 's'

            for (deviceIndex in devices) { // what specific device are we looking at?
                var device = [];
                device = devices[deviceIndex];

                for (valueIndex in device[0].values) { // what are the values associated with this device?
                    var xValue = [];
                    var yValue = [];

                    xValue = (device[0].values[valueIndex].the_time);
                    yValue = (device[0].values[valueIndex].is_active);

                    values.push([xValue, yValue]);

                }
            }
        }
    }
    console.log("plotData has run");
    console.log(values[0]);
};

function test() {
    console.log(typeof houses);
    console.log(typeof values);
    console.log("test has run");
};

the output I keep getting on the console log is as follows:

plotData has run (16:25:13:673)
  at public_html/js/main.js:51
undefined (16:25:13:674)
  at public_html/js/main.js:52
object (16:25:13:674)
  at public_html/js/main.js:56
object (16:25:13:674)
  at public_html/js/main.js:57
test has run (16:25:13:675)
  at public_html/js/main.js:58
undefined (16:25:15:452)
  at public_html/js/main.js:19
getData has run (16:25:15:453)
  at public_html/js/main.js:20

which is kind of right for what I'm asking but if I ask..

console.log(houses)

..I get nothing. And if I'm more specific like

console.log(houses[0][0])

I just get an error. Usually -

Uncaught TypeError: Cannot read property '0' of undefined

I don't know if it's just a syntax error on my part or if I'm completely on the wrong track so any help would be great. I've also noticed that in the console, certain functions seem to be finished before others so maybe that could be a problem?

I'm pretty new to this so apologies for any glaring oversights and thanks in advance for any help.

don't use for in for arrays, use for loop instead. for in is for objects not arrays

  for (var houseIndex = 0 ; houseIndex < houses.length; houseIndex++) {

    // your code
    }

the ajax call in getData() is asynchronous. so plotData() will execute before the callback, so well test().

You basically want your plotData() to be called in the call back like this.

 function getData() { $.getJSON("http://dev.modusdeus.com/f_fridge/all_events.php", function (data) { consoloe.log(data); houses.push(data); console.log(data[0].devices.device_type); console.log("getData has run"); plotData(); test(); }); }; 

also, notice how your console.log(data[0].devices.device_type); is returning undefined. That's because devices is an array and you are referencing a property on it, it needs be something like console.log(data[0].devices[0].device_type);

Your JSON does not seem to hold data uniformly as well. The very first entry has a devices array that has a single value, but your subsequent entries are objects.

Finally, as noted in another answer, the "for in" syntax is for iterating over object properties and not for iterating over arrays.

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