0

I have been using code from other questions on stackoverflow such as here and here.

I get the error Uncaught TypeError: Cannot read property 'length' of undefined that I can see in the developer console when I try to run my function. This error is within the jQuery file itself supposedly, not in my code. (I know ofc it is still my own error somewhere).

Here is the code I'm trying to execute:

function populate_api(){
    var json = (function () {
        var json = null;
        $.ajax({ 
            'async': false,
            'global': false,
            'url': "test.txt",
            'dataType': "json",
            'success': function (data) {
                json = data;
            }
        });
        return json;
    })(); //^-from SOflow: https://stackoverflow.com/questions/2177548/load-json-into-variable
    //Put the JSON into a variable ---^


    $.each(json.result.matches.players, function(i, v){
        if (v.account_id == 38440257) {
            alert(v.hero_id);
                return;
        }
    }); //use variable to run a search on the JSON tree --^
}

The file itself with the Json in has quite a lot of info, but this is the small area at the top of the file I've been testing with:

{
    "result": {
        "status": 1,
        "num_results": 10,
        "total_results": 500,
        "results_remaining": 490,
        "matches": [
            {
                "match_id": 514348401,
                "match_seq_num": 468628758,
                "start_time": 1392061295,
                "lobby_type": 7,
                "players": [
                    {
                        "account_id": 38440257,
                        "player_slot": 0,
                        "hero_id": 42
                    },
...

To quickly summarise again. I am searching for the "hero_id" where the account ID is 38440257 within the matches tree.

Community
  • 1
  • 1
k4kuz0
  • 1,045
  • 1
  • 10
  • 24

3 Answers3

1

It's because json.result.matches.players is undefined and jQuery.each() doesn't have any checks for the first argument being undefined, it instead assumes you're passing it something valid that it can access the length property of.

In your JSON json.result.matches is an array of objects (each one representing a match), and each of those objects has a players property; the array itself does not have a players property. You need to iterate through each of the matches first, then through each of its players:

$.each(json.result.matches, function(index, match) {
    $.each(match.players, function(i, v) {
        // code here
    });
});

Alternatively just check the players for a particular match (in this case, the first one):

$.each(json.result.matches[0].players, function(i, v) {
    // code here
});

You should also move away from synchronous AJAX calls (such a ridiculous notion...) and instead call functions with your data processing logic from the success callback function, passing the JSON in.

Anthony Grist
  • 38,173
  • 8
  • 62
  • 76
  • Thanks for the detailed reply. I will check it in a moment. With regards to the synchronous ajax calls, I was just using the code I saw in the top answer [here](http://stackoverflow.com/questions/2177548/load-json-into-variable) – k4kuz0 Feb 11 '14 at 10:39
  • Just tested it and it works perfectly. Thank you again. – k4kuz0 Feb 11 '14 at 10:45
1

You can always check if json is undefined before using it, like this:

if (typeof json != 'undefined') {
   // Do things with json
}

And you could wrap it in your success callback, and check if data is defined before using it, skipping the return json part all together:

function populate_api() {
    $.ajax({
        'async': false,
            'global': false,
            'url': "test.txt",
            'dataType': "json",
            'success': function (data) {
            if (typeof data != 'undefined') {
                $.each(data.result.matches, function (i, v) {
                    v.players.forEach(function(player){
                        if (player.account_id == 38440257) {
                            alert(player.hero_id);
                        }
                    });
                });
            }
        }
    });
}
ojovirtual
  • 3,332
  • 16
  • 21
Magnus Engdal
  • 5,446
  • 3
  • 31
  • 50
  • I have just tested the code you posted above, and I still get the same error. So I guess I can assume that there is a problem with putting a value into the json variable? I'm still not sure where that error is however. I'm in unfamiliar territory. – k4kuz0 Feb 11 '14 at 10:34
  • @k4kuz0 Your issue is iterating through the JSON, see my answer. – Anthony Grist Feb 11 '14 at 10:36
  • In your JavaScript Console, you should be able to put a breakpoint after a successful callback to see what `data` and `json` contains. – Magnus Engdal Feb 11 '14 at 10:36
0

You are getting the json variable value outside of the "success" function, so it will execute before the ajax call has ended. Try changing this way:

'success': function (json) {
            return json;
        }
    });
ojovirtual
  • 3,332
  • 16
  • 21