jQuery - Save each pair without explicitly declaring each pair

I'm trying to parse this JSON file (edited down to save space)

{
    "status": "ok",
    "count": 1,
    "data": {
        "1002009609": {
            "clan": null,
            "achievements": {
                "medal_le_clerc": 1,
                "tank_expert_ussr": 1,
                "evileye": 66,
                "mechanic_engineer_china": 1,
                "medal_nikolas": 0,
                "scout": 834
            },
                "all": {
                    "spotted": 152645,
                    "hits": 444587,
                    "battle_avg_xp": 423,
                    "draws": 1145,
                    "wins": 42739,
                },
                "company": {
                    "spotted": 18,
                    "hits": 84,
                    "battle_avg_xp": 573,
                    "draws": 0,
                    "wins": 19,
                },
                "max_xp": 2530
            },
            "nickname": "Definder"
        }
    }
}

But rather than go through each item and use data.data[i].____ is there a way I can store each pair without specifically declaring each name?

Right now I'm using this:

$.getJSON(linkClicked, function (data) {
    var person = data.data[id], array = [];
    if (person) {
        array.push('<h3>' + person.nickname + '</h3>');
        array.push('<div class="achievements"><h5>Achievements</h5><ul>');
        array.push('<li>diehard: ' + person.achievements.diehard + '</li>');
        array.push('<li>kamikaze: ' + person.achievements.kamikaze + '</li>');
        array.push('<li>iron_man: ' + person.achievements.iron_man + '</li>');
        array.push('</ul></div>'); //end of achievements
    }
    $('#person').html(array.join(''));
});

But I was hoping I go into achievements and just push each pair using a loop of sorts, then go onto all and so on.

Here's a JSFiddle link of the project so far.

Thanks in advance!

Answers


jsFiddle Demo

You are going to need recursion to do that. Sure, you could use each or a single for in loop but these will only graze the surface of what is a complex object.

Call a recursive function from your click event handler using the parent (person) and passing in the array to build.

if (person) {
 array.push('<h3>' + person.nickname + '</h3>');
 buildDisplay(person,array,true);
}

Next, make the recursive buildDisplay function.

function buildDisplay(parent,arr,top){
    for( var item in parent ){
        if(toString.call(parent[item]) == "[object Object]"){
            arr.push('<div class="'+item+'"><h5>'+item+'</h5><ul>');
            buildDisplay(parent[item],arr,false);
            arr.push('</ul></div>');
        }else{
            if(top)continue;
            arr.push('<li>'+item+': ' + parent[item] + '</li>');
        }
    }
}

And now you are ready to see the results


You can use jQuery's each function:

var PERSON_OBJECTS = ["achievements", "all", "company"];
function capitalize(string) {
  return string.replace(/\b[\w]/g, function(match){return match.toUpperCase()});
}

....

$.each(PERSON_OBJECTS, function(name) {
  array.push('<div class="'+name+'"><h5>'+capitalize(name)+'</h5><ul>');
  $.each(person[name], function(value, key) {
    array.push('<li>'+key+': '+value+'</li>');
  });
  array.push('</ul></div>');
});

I'd recommend $.each over for in as for in can often produce unexpected results.

var person = data.data[id], array = [];
array.push('<h3>' + person.nickname + '</h3>');
//begin of achievements
$.each(person.achievement, function(key, item){
  array.push('<li>' + key + ':' + item + '</li>');
});
array.push('</ul></div>'); //end of achievements

Need Your Help

Capture UIView in RubyMotion

ios objective-c ruby uiimage rubymotion

I want to capture an UIView as an UIImage. I've tried many things, but I always get this kind of error :

only 1 row in add more row in form using javascript is working

javascript php jquery mysql

I have an order page with items drop down selected from mysql. If I click on add more, It works but when I enter quantity, select items and services. Only the last one is entered into the database ...