London804
London804

Reputation: 1126

Accessing json objects with no name

I'm struggling to access this json code below. Every json value I've previously seen is something like this:

 var hold = { name: 'alex', job: 'realtor'}

So to access the name I would do something like hold.name. But my json data looks like this

[
    [
        {
            "count": "80",
            "countTxt":"Buyer logins",
            "participantsTxt":"Total for all participating member companies:",
            "participantCount":"523"
        },
        {
            "count": "233",
            "countTxt":"Searches",
            "participantsTxt":"Total for all participating member companies:",
            "participantCount":"628"
        },
        {
            "count": "533",
            "countTxt":"Views of our member pages",
            "participantsTxt":"Total for all participating member companies:",
            "participantCount":"2,365"
        }
    ],
    [
        {
            "count": "80",
            "countTxt":"Total vists",
            "participantsTxt":"Total for all participating member companies:",
            "participantCount":"412"
        },
        {
            "count": "53",
            "countTxt":"Unique visitors",
            "participantsTxt":"Total for all participating member companies:",
            "participantCount":"731"
        },
        {
            "count": "1:12 min",
            "countTxt":"Total time spent on page",
            "participantsTxt":"Total for all participating member companies:",
            "participantCount":"784.2 mins"
        }
    ]
]

The data is nested and it has no name so I don't know how to access. I know the question seems somewhat rudimental but I haven't seen any examples parse code that looks like this. It's always a more simple example like the one above. My .getjson code looks like this ...

var requestURL = 'assets/js/stats.json';
$.getJSON(requestURL, function(data){
        $.each(data, function(key, value) {
            $('body').append($('<div>' + data[0].name, {

            }));
            console.log(data);
        });

    });

My console is returning two objects that look like this

Array[3], Array[3]] Array[3]: 
Array[3] [Array[3], Array[3]] 

So I know it's getting data back I just need to be able to pick what I want a append it to the DOM. I've tried ten different variations but nothing works. Please help!?

Upvotes: 1

Views: 4135

Answers (2)

JakeRobb
JakeRobb

Reputation: 1980

The asker shows a confusion between objects and arrays. Objects are surrounded by curly braces ({...}), whereas arrays use square brackets ([...]).

An object has named elements known as "key-value pairs," as in the example:

var hold = { name: 'alex', job: 'realtor'}

First of all, I'll note that the above is not valid JSON. Object keys in JSON must always be quoted. As valid JSON, we'd be looking at:

{ "name": "alex", "job": "realtor" }

name and job are keys, and alex and realtor are the values that correspond to those keys, respectively. These entries are not considered to be in any particular order. This data structure is commonly known as a map or a dict(ionary) in other programming languages.

In JavaScript (and its vastly superior cousin, TypeScript), you can address the keys in an object two ways:

  • Dot notation: hold.name
  • Bracket notation: hold['name']

They are equivalent, but dot notation won't work if the element's key is not a valid identifier. Let's say you have this super-contrived example stored in hold:

{ "name": "alex", "job*title": "realtor" }

hold.job*title will fail because it will parse as hold.job multiplied by title. undefined * undefined is undefined. Not what we wanted! Instead, you would need to use hold['job*title'], which would resolve to 'realtor' like we expected.

Arrays, on the other hand, are just an ordered list. To access their contents, we always use square bracket notation. For example, if we're given:

var data = ['alex', 'realtor'];

Then we can access the values alex and realtor as data[0] and data[1], respectively. Furthermore, unlike objects, order is a primary aspect of an array. You can ask the computer to do something for each element in an array, and it will always do it in the same order, from [0] through [n-1], where n is the number of elements in the array. Arrays are a standard feature of pretty much every modern programming language, and are almost always called arrays. Sometimes you'll see them called Lists.

Okay, with that bit out of the way, we can move on. As we go, we'll address some other issues with your code.

First: inside your $.each loop, you're trying to reference data[0].name. But data is your complete JSON response; you wouldn't generally want to use that inside the loop. Instead, use your loop variable, value:

var requestURL = 'assets/js/stats.json';
$.getJSON(requestURL, function(data){
    $.each(data, function(key, value) {
        $('body').append($('<div>' + value[0].name, {}));
        console.log(data);
    });
});

In your JSON data, you have objects inside nested arrays:

[
    [
        {
           ...
        }
    ],
    [
        {
           ...
        }
    ]
]

In the example, each inner array contains exactly one element. I can't tell from just one example whether that's always the case. If it's not, you'll need to iterate the inner array as well by nesting an additional call to $.each:

var requestURL = 'assets/js/stats.json';
$.getJSON(requestURL, function(data){
    $.each(data, function(key, innerList) {
        $.each(innerList, function(key, item) {
            $('body').append($('<div>' + value.name, {}));
            console.log(data);
        });
    });
});

I'll run with the assumption that there can be more than one element in the inner array. This code will work even if that's not the case.

Finally, let's refer back to your JSON. Each item looks like this:

{
    "count": "80",
    "countTxt":"Total visits",
    "participantsTxt":"Total for all participating member companies:",
    "participantCount":"412"
}

It doesn't have a .name, so value.name is going to be undefined. I'm not sure what it is you want to display, so for the purposes of this answer I'll just guess that we want to display something like 80 Total visits:

var requestURL = 'assets/js/stats.json';
$.getJSON(requestURL, function(data){
    $.each(data, function(key, innerList) {
        $.each(innerList, function(key, value) {
            $('body').append($('<div>' + value.count + ' ' + value.countTxt));
            $('body').append(div);
            console.log(value);
        });
    });
});

But now there's one more issue: the way we're creating that div isn't correct. You have to tell jQuery what kind of tag you want and what you want its contents to be separately:

var requestURL = 'assets/js/stats.json';
$.getJSON(requestURL, function(data){
    $.each(data, function(key, innerList) {
        $.each(innerList, function(key, value) {
            var div = $('<div>');
            div.text(`${value.count} ${value.countTxt}`);
            $('body').append(div);
            console.log(value);
        });
    });
});

Note that, as a best practice, you should make sure that getJSON also handles the case where the API call fails. As written, this entire block of code will simply get skipped, with no apparent indication to the user.

Upvotes: 0

user2432612
user2432612

Reputation: 188

You just need to iterate one more time inside first iteration. You have one array that holds array of objects. So try something like this

http://jsfiddle.net/mnth1xe1/5/

$.each(data, function(key, val) {
    $.each(val, function(key, value) {

        console.log(value.countTxt);
    });

});

Upvotes: 1

Related Questions