2

i am trying to get a JSON and access its objects to retrieve data, all my paths seems to be working good but one specifically is not working. I just checked and the path is the same the other objects i am trying to access, in the console i keep getting undefined as a result. i will appreciate if you guys could tell me whats wrong with the code i will leave you the JSON structure and also the java Scripti hope you guys can help me figuring out, and also would be good if you could give me some tips on my coding because I am learning.

Java Script: This function is called when you click on some item in a list.

function checkUser(){
    console.log("clicked");
    var user = $(this).html();
    $.getJSON("js/options.json", function(json){
        var itemsLength = json.chat.OnlineContacts.length;
        for ( var i = 0; i < itemsLength; i++) {
            var jsonUserName = json.chat.OnlineContacts[i].name;
            var jsonUserStatus = json.chat.OnlineContacts[i].status;
            var jsonUserAvatar = json.chat.OnlineContacts[i].avatar;
            if(user == jsonUserName){
                /*displayChatWindow(jsonUserName, jsonUserStatus, jsonUserAvatar);*/
                console.log(jsonUserAvatar);
             }
         };
    });
}

function displayChatWindow(user, status, avatar){
    /*var template = _.template($("#windowTemplate").html(), {userName: user, userStatus: status, userAvatar: avatar});
    $("body").prepend(template);*/
    $(".messages-container").slimScroll({
        height: '200',
        size: '10px',
        position: 'right',
        color: '#535a61',
        alwaysVisible: false,
        distance: '0',
        railVisible: true,
            railColor: '#222',
        railOpacity: 0.3,
        wheelStep: 10,
        disableFadeOut: false,
        start: "bottom"     
    });
}

And this is the JSON:

{
"chat": {
    "NumberOfOnlineContacts": "7",
    "NumberOfOfflineContacts": "800",
    "OnlineContacts": [
        {
            "name": "Nandy Torres",
            "status": "online",
            "avatar": "img/profile-picture2.jpg"
        },
        {
            "name": "Catherine Varela",
            "status": "Busy",
            "avatar": "img/profile-picture3.jpg"
        },
        {
            "name": "Jhonnatan Gonzalez",
            "status": "online",
            "avatar": "img/profile-picture4.jpg"
        },
        {
            "name": "Juan Prieto",
            "status": "away",
            "avatar": "img/profile-picture5.jpg"
        },
        {
            "name": "Alexander Barranco",
            "status": "Busy",
            "avatar": "img/profile-picture6.jpg"
        }
    ],
    "OfflineContacts": [
        {
            "name": "Nandy Torres"
        },
        {
            "name": "Catherine Varela"
        },
        {
            "name": "Jhonnatan Gonzalez"
        },
        {
            "name": "Juan Prieto"
        },
        {
            "name": "Jhonathan Sanchez"
        }
    ]
}
}

When I try to do the console log on avatar like is in the example I just get undefined, but if i do console.log of name or status y just get the correct values.

  • 1
    *Which* path is not working? Please be specific in your questions – Explosion Pills Jun 06 '13 at 20:22
  • @ExplosionPills I believe `json.chat.OnlineContacts[i].avatar` is the path that's not working, judging by the `console.log()` statement. – ayyp Jun 06 '13 at 20:24
  • Yea thats right i just scpecified at the end of the question "When I try to do the console log on avatar like is in the example I just get undefined, but if i do console.log of name or status y just get the correct values." if i change the name in the JSON to picture and also the path to picture i get the console.log but if i un comment the lines I commented I get an error that says : ReferenceError: jsonUserAvatar is not defined. – Jhonnatan Gonzalez Rodriguez Jun 06 '13 at 20:27
  • @JhonnatanGonzalezRodriguez are you sure you've given us the right JSON? http://jsfiddle.net/ExplosionPIlls/NVFGV/ – Explosion Pills Jun 06 '13 at 20:32
  • @ExplosionPills Yeah it was the right JSOn i think the problem was on the underscore variables, they were setted wrong, i just changed them and know everything is working right Thank you every one...i will also recieve some advice if im doing good coding or its a mess :) – Jhonnatan Gonzalez Rodriguez Jun 06 '13 at 20:34

2 Answers2

2

Consider restructuring the original JSON object so you can access users directly by their unique id - in this case it appears to be "name".

For example:

{
    "chat": {
        "NumberOfOnlineContacts": "7",
        "NumberOfOfflineContacts": "800",
        "OnlineContacts": [
            {
                "Nandy Torres" : {
                    "status": "online",
                    "avatar": "img/profile-picture2.jpg"
                }
            },
            {
                "Catherine Varela" : {
                    "status": "Busy",
                    "avatar": "img/profile-picture3.jpg"
                }
            },
            {...}
        ]
    }
}

This could be accessed in the following ways without the expense of a loop:

json.chat.OnlineContacts[0].avatar
json.chat.OnlineContacts["Nandy Torres"].avatar
json.chat.OnlineContacts[user].avatar

There's an obvious cost-benefit here, but you may get the best of both by inlcuding the "name" attr as well:

"Nandy Torres" : {
    "name": "Nandy Torres",
    "status": "online",
    "avatar": "img/profile-picture2.jpg"
}

And eventually moving to a more formal unique id:

"123abc" : {
    "name": "Nandy Torres",
    "status": "online",
    "avatar": "img/profile-picture2.jpg"
}

There's lots of excellent ideas for structuring JSON at json.com

Dave Romero
  • 128
  • 6
  • 1
    Wow this is really cool because what i am doing is thinked to be kind of "scalable" so organizing the JSON in that way would be really cool to keep it really organized in the future. – Jhonnatan Gonzalez Rodriguez Jun 06 '13 at 21:18
  • Excellent post! I definitely recommend starting with the unique ID at the very beginning, though - I don't think you want to depend on people's names being unique. And BTW we must be on some kind of psychic wavelength today, because earlier I was recommending a [similar JSON restructuring](http://stackoverflow.com/questions/16970265/find-json-nested-nodes-using-multiple-string-values/16971541#16971541). – Michael Geary Jun 06 '13 at 21:32
  • Thanks Michael and great point about starting with the unique id first! Let's keep the psychic wavelength flowing :) – Dave Romero Jun 06 '13 at 22:17
2

Jhonnatan, I'm glad you got your code working. So this isn't really an "answer" to your original question. But you also asked for tips on the coding and how to improve it. That's great that you're looking for ways to improve your code!

Here's one suggestion for you, a simpler way to write the checkUser() function. This is just a direct conversion of your function that should work with the same data format.

function checkUser() {
    console.log( "clicked" );
    var user = $(this).html();
    $.getJSON( "js/options.json", function( json ) {
        $.each( json.chat.OnlineContacts, function( i, contact ) {
            if( user == contact.name ) {
                displayChatWindow( contact.name, contact.status, contact.avatar );
                console.log( contact.avatar );
             }
         });
    });
}

Note how the use of the contact object makes it unnecessary to create all those jsonUserXxxx variables, because code like contact.avatar is just as simple and clear as jsonUserAvatar.

I also highly recommend @DaveRomero's excellent answer for a more strategic look at the question of how best to structure your JSON data.

More related reading: this discussion of JSON restructuring that I posted in response to this question earlier today.

Community
  • 1
  • 1
Michael Geary
  • 28,450
  • 9
  • 65
  • 75
  • Hello Michael, thank you for taking the time to answer and also add all that material and examples :). when you refer to an object I got a question. Like "contact.avatar" how can i convert the json I get by $.getJSON in to an object like contact={} as you said. I dont really get it on how to convert all the data in the json to an object, or is the $,each doing it for me? I am sorry if the question is not 100% understandable, english is not my main lenguage so I am doing a great effor lol. – Jhonnatan Gonzalez Rodriguez Jun 06 '13 at 21:34
  • 1
    @JhonnatanGonzalezRodriguez - Yes, `$.each` provides that `contact` object to its callback function. In your original code, `json.chat.OnlineContacts` is already an array of `contact` objects, right? That's why you could use `json.chat.OnlineContacts[i]` to get to one of those objects, or `json.chat.OnlineContacts[i].avatar` to get to one avatar. `$.each` just loops through the array for you, and calls the nested callback function for each array element, passing it the array index and array value - the `contact` object - as parameters. (And BTW your English is very good!) – Michael Geary Jun 06 '13 at 21:41