Jquery object is undefined after sort but is in firebug

215 Views Asked by At

I do an ajax call to a script that returns data. I see the data in firebug and it is correct. When the data comes back I do a sort and it works too. I see in firebug the object is sorted the way I want. After the sort I try to access a key/value pair. I see in firebug that the key/value I want is in the object. When I try to use the object key/value to assign to a var it is undefined. I'm trying to aggregate repeating data. If I'm not using the best way to do it, please help me with a better method.

data sample

coreDate "060115" coreType "asterisk_11" fileName "/var/www/html/Cores/gdb.hamid.asterisk.060115" jid "hamid"

code

    $.when (
            $.ajax( {
                    type:"GET",
                    url: 'cf.php',
                    dataType: 'json',
                    timeout: 120000,
            })
    )
    .done(function(coreInfo) {
            coreInfo.sort(function(a,b) { return a.coreType > b.coreType } );
            var coreStats={};
            coreStats.numOfCores=0;
            coreStats.numOfCoreType=0;
            coreStats.prevCoreType=coreInfo.coreType;
// for some reason coreInfo.coreType is not defined.  The coreInfo object exists and coreType is there.  I tried this.coreType but is undefined.
            $.each(coreInfo, function() {
                    coreStats.numOfCores++;
                    if (coreStats.prevCoreType != this.coreType) {
// This works.  why do I have to access this.coreType instead of coreInfo.coreType?
                            $('#list > tbody:last-child').append('<tr><td><a href="'+this.fileName+'">'+this.coreType+'</td><td>'+coreStats.numOfCoreType+'<br>core</td><td>jid</td></tr>');
                            coreStats.numOfCoreType=0;
                    }
                    coreStats.numOfCoreType++;
                    coreStats.prevCoreType=this.coreType;
// setting prevCoreType works here
            });
            $('#cores').html("<h1>"+coreStats.numOfCores+"</h1><br>Core Files");
    })
    .fail(function() {
    });
1

There are 1 best solutions below

4
On BEST ANSWER

From your code and description, it sounds like coreInfo is an array of objects, is that right? If it were an object, it wouldn't have a sort() method and your code would stop right there.

If it's an array, it doesn't have a property like coreInfo.coreType. Each element of the array is an object with coreType and other properties. That's why you are able to access this.coreType inside the $.each() callback. $.each() iterates through the array, element by element, and passes each individual element into the callback.

Where it looks like you're seeing coreInfo.coreType in Firebug outside the $.each(), I suspect that what you're actually seeing is coreInfo[0].coreType, i.e. the first element of the array.

To help keep track of whether a variable is an array or not I strongly suggest giving arrays names that reflect this fact: either a plural word, or add List or Array to the name, or something. A name like coreInfo sounds like a singular item. I would call the array coreList, coreArray, or simply cores. Personally I like plural words for brevity: cores for the array of core info, core for an individual element in that array.

This way when you see cores.coreType or coreList.coreType or coreArray.coreType it will look wrong.

BTW for much more readable code, I suggest never using this in a $.each() callback. Instead, use named parameters.

$.each( coreInfo, function( i, core ) {
    coreStats.numOfCores++;
    if( coreStats.prevCoreType != core.coreType ) {
        $('#list > tbody:last-child').append(
            '<tr>' +
                '<td>' +
                    '<a href="' + core.fileName + '">' +
                        core.coreType +
                    '</a>' +  // MISSING IN ORIGINAL
                '</td>' +
                '<td>' +
                    coreStats.numOfCoreType +
                    '<br>core' +
                '</td>' +
                '<td>' +
                    'jid' +
                '</td>' +
            '</tr>'
        );
        coreStats.numOfCoreType = 0;
    }
    coreStats.numOfCoreType++;
    coreStats.prevCoreType = this.coreType;
});

Note that there was a missing </a> in your markup in the code above. It's much easier to spot an error like this if you indent the markup strings in the same way that you might indent raw HTML code, instead of cramming it all onto one line.

A minor point: You don't need to wrap $.ajax() inside $.when(). $.ajax() returns a Promise that you can use directly.

You don't need the code that computes coreStats.numOfCores. You can simply use the length property of the array. If you follow my suggestion to call the array cores you could do this:

$('#cores').html( "<h1>" + cores.length + "</h1><br>Core Files" );

Finally, your sort callback function has a bug and will not sort the array properly. It may have worked in a simple test case, but it will fail to sort other arrays. It has to handle all three cases: <, ==, and > and return an appropriate value for each case, perhaps like this:

coreInfo.sort( function( a, b ) {
    return(
        a.coreType < b.coreType ? -1 :
        a.coreType > b.coreType ? 1 :
        0
    );
});

To verify my assumptions, can you post an example of your actual JSON data, not a formatted table?