Generating multi-level JSON

javascript, json

Solution

This should work.

var json = [];
var linkData;
for (var i = 0; i < tourList.length; i++) {
    var data = tourList[i];
    //create new child array for insertion
    var child = [{ }];

    //push location marker data
    child[0]['location'] = [{
        latitude: data.location.position.$a,
        longitude: data.location.position.ab,
        stopNum: i,
        filename: data.location.title
    }];

    child[0]['links'] = [];

    //add associated link data
    for (var j = 0; j < data.links.length; j++) {
        linkData = data.links[i];
        child.links.push({
            latitude: linkData.position.$a,
            longitude: linkData.position.ab,
            stopNum: i + j,
            fileName: linkData.title
        });
    }
    //push to json array
    json.push(child);
}

//stringify the JSON and post results
var results = JSON.stringify(json);

But why are you making the output JSON so complex? A simpler way would be to use something like this:

item1: {
    "location": {
        "latitude": value, "longitude": value, "stopNum": value, "fileName": value
    },
   "links": [
      {"latitude": value, "longitude": value, "stopNum": value, "fileName": value },
      {"latitude": value, "longitude": value, "stopNum": value, "fileName": value },
      {"latitude": value, "longitude": value, "stopNum": value, "fileName": value }
    ]
},
item2: [ //repeat of above ]

What you are doing is creating 'arrays' for single objects. Why do that? If you use this format, the code (subtly) simplifies:

var json = [];
var linkData;
for (var i = 0; i < tourList.length; i++) {
    var data = tourList[i];
    //create new child array for insertion
    var child = { };

    //push location marker data
    child.location = {
        latitude: data.location.position.$a,
        longitude: data.location.position.ab,
        stopNum: i,
        filename: data.location.title
    };

    child.links = [];

    //add associated link data
    for (var j = 0; j < data.links.length; j++) {
        linkData = data.links[i];
        child.links.push({
            latitude: linkData.position.$a,
            longitude: linkData.position.ab,
            stopNum: i + j,
            fileName: linkData.title
        });
    }
    //push to json array
    json.push(child);
}

//stringify the JSON and post results
var results = JSON.stringify(json);

Problem

I have an array of Objects, each containing a Location and a Links array of indeterminate length. How can I create a multilevel JSON object with loops? The end JSON should look like ``` item1: [ { "location": [ {"latitude": value, "longitude": value, "stopNum": value, "fileName": value } ], "links": [ {"latitude": value, "longitude": value, "stopNum": value, "fileName": value }, {"latitude": value, "longitude": value, "stopNum": value, "fileName": value }, {"latitude": value, "longitude": value, "stopNum": value, "fileName": value } ] } ], item2: [ //repeat of above ] ``` The issue I'm having is how to correctly form the objects. The objects that the array contains are defined as ``` function Links(){ this.location = null; this.links= []; function getLocation(){ return location; } function setLocation(marker){ this.location = marker; } function getLinks(){ return links; } } ``` My current solution is ``` var json=[]; var linkData; for (var i=0; i < tourList.length; i++){ var data = tourList[i]; //create new child array for insertion var child=[]; //push location marker data child.push({ latitude: data.location.position.$a, longitude: data.location.position.ab, stopNum: i, filename: data.location.title }); //add associated link data for (var j=0; j<data.links.length; j++){ linkData = data.links[i]; child.push({ latitude: linkData.position.$a, longitude: linkData.position.ab, stopNum: i+j, fileName: linkData.title }); } //push to json array json.push(child); } //stringify the JSON and post results var results= JSON.stringify(json); ``` However, this is not quite working, as ``` $post= json_decode($_POST['json']) ``` PHP statement is returning a malformed array where `$post.length` is seen as an undefined constant. I'm assuming that this is due to the incorrect formatting. With objects defined above, how can I create a well-formed JSON to be sent to the server? The current result of `stringify()` is ``` [ {"latitude":43.682211,"longitude":-70.45070499999997,"stopNum":0,"filename":"../panos/photos/1-prefix_blended_fused.jpg"}, [ {"latitude":43.6822,"longitude":-70.45076899999998,"stopNum":0,"fileName":"../panos/photos/2-prefix_blended_fused.jpg"} ], {"latitude":43.6822,"longitude":-70.45076899999998,"stopNum":1,"filename":"../panos/photos/2-prefix_blended_fused.jpg"}, [ {"latitude":43.68218,"longitude":-70.45088699999997,"stopNum":1,"fileName":"../panos/photos/4-prefix_blended_fused.jpg"}, {"latitude":43.68218,"longitude":-70.45088699999997,"stopNum":2,"fileName":"../panos/photos/4-prefix_blended_fused.jpg"} ] ] ``` Also, I'm using `$post.length` in ``` $post = json_decode($POST['json']); for ($i=0; $i<$post.length; $i++) { } ``` to iterate over the processed array. The POST request is via a `jQuery.ajax()` function defined as ``` $.ajax({ type: "POST", url: "../includes/phpscripts.php?action=postTour", data: {"json":results}, beforeSend: function(x){ if (x && x.overrideMimeType){ x.overrideMimeType("application/json;charset=UTF-8"); } }, success: function(data){ if (data == "success") console.log("Tour update successful"); else console.log("Tour update failed"); } }); ```

Original source