Jay Rizzi Jay Rizzi - 4 months ago 11
JSON Question

Find JSON nested nodes using multiple string values

I have a screen that needs to calculate prices based on two different parameters, primary (activity in example) and children (ticketType in example)

Previously this was done hackishly, so i decided the best option would be to store the prices in a JSON object populated at runtime, and based on clicks & change events

So i have this json format I formulated, please note you can change this as well, not set in stone

{
"activities": [{
"activitycode": "TK",
"desc": "Tickets",
"ticketTypes": [{
"ticketcode": "G",
"baseprice": 79
}, {
"ticketcode": "P",
"baseprice": 109
}]
}, {
"activitycode": "PK",
"desc": "Parking",
"ticketTypes": [{
"ticketcode": "BK",
"baseprice": 65
}, {
"ticketcode": "ESC-I",
"baseprice": 40
}]
}], //end activities
"handlingPercent": "0.03",
"shipping": "15"
}


So, I tried traverse the JSON object for the correct price, like this

pricing.activities.activitycode['TK'].ticketTypes.ticketcode['G'].baseprice


but this doesnt work, because I havent specified which numerical node to go to yet before supplying my values

Once i did that, the following works

pricing.activities[0].ticketTypes[0].baseprice


But what i would like to accomplish is supplying string/text values, traverse parent nodes, then child nodes, and find the value

I suppose i could do an $.each iteration like this, but i wanted to know what the experts thought first, if this is indeed the best way to go about things

$.each(pricing.activities, function(arrayID, activityData) {
if(activityData.activitycode=="TK")
$.each(activityData.ticketTypes, function(ticketTypeID, typeData) {
if(typeData.ticketcode=="G")
alert(typeData.baseprice);
});
});

Answer

Before talking about the code, let's talk about your JSON data.

First, I reformatted the data so I could follow the structure more easily:

{
    "activities": [
        {
            "activitycode": "TK",
            "desc": "Tickets",
            "ticketTypes": [
                { "ticketcode": "G", "baseprice": 79 },
                { "ticketcode": "P", "baseprice": 109 }
            ]
        },
        {
            "activitycode": "PK",
            "desc": "Parking",
            "ticketTypes": [
                { "ticketcode": "BK", "baseprice": 65 },
                { "ticketcode": "ESC-I", "baseprice": 40 }
            ]
        }
    ],
    "handlingPercent": "0.03",
    "shipping": "15"
}

Now that the structure is clear, here is the question: You have an activities array, and inside each of the elements of that array there is a ticketTypes array.

Does the order of items in these arrays matter? i.e. are they used to generate a display list that must be in the correct order?

And, how do you need to access these arrays? Do you primarily loop through them and do something with all the elements? Or do you use them to look up individual elements given a known activitycode and ticketcode - which is what the nested $.each loops at the end of your question end up doing?

Depending on the answers to these questions, you may be better served with a different kind of structure. Perhaps like this:

{
    "activities": {
        "TK": {
            "desc": "Tickets",
            "ticketTypes": {
                "G": { "baseprice": 79 },
                "P": { "baseprice": 109 }
            }
        },
        "PK": {
            "desc": "Parking",
            "ticketTypes": {
                "BK": { "baseprice": 65 },
                "ESC-I": { "baseprice": 40 }
            }
        }
    },
    "handlingPercent": "0.03",
    "shipping": "15"
}

Because now this code (I cleaned up the indentation here too):

$.each( pricing.activities, function( arrayID, activityData ) {
    if( activityData.activitycode=="TK" ) {
        $.each( activityData.ticketTypes, function( ticketTypeID, typeData ) {
            if( typeData.ticketcode=="G" )
                alert( typeData.baseprice );
         });
    }
});

can be replaced with:

alert( pricing.activities.TK.ticketTypes.G.baseprice );

and other similar code that you write will also be simpler. About the only thing you lose this way is the guarantee of ordering of the activities and ticketTypes: arrays have a guaranteed order, objects do not.