Jamie Hartnoll
Jamie Hartnoll

Reputation: 7341

data.length is undefined following a successful getJSON operation

I'm populating a drop down with JSON data from getJSON.

Populating is working fine, but trying to establish that it's finished by comparing to data.length is not working as data.length is undefined and I can't see why!

The data looks like:

{
    "1": {
        "id": "1",
        "name": "Plymouth"
    },
    "2": {
        "id": "2",
        "name": "Torquay"
    }
}

My code looks like:

$('.locationList').empty();
$('.locationList').append('<option value="">Select...</option>');
$.getJSON('/Settings/locations.txt', function (data) {
    var dataNum = data.length;
    var counter = 1;
    $.each(data, function (i, item) {
        $('.locationList').append('<option value="' + data[i].id + '">' + data[i].name + '</option>');
        if (counter >= dataNum) {
            $('#bookTo').val(locationID + 1);
            $('#transferFrom').val(locationID);
        };
        counter++;
    });
});

This section:

if (counter >= dataNum) {
    $('#bookTo').val(locationID + 1);
    $('#transferFrom').val(locationID);
};
counter++;

Is meant to allow me to preset the values of the drop down boxes once the $.each loop has completed (this works with other lists), but it's not happening.

When I run alert(data.length) I get undefined which makes no sense as data clearly does have a length in order for it to populate the drop down box properly through the $.each, which it does!

EDIT: sorry, should add, the variable locationID is declared earlier in the script from a Cookie and IS valid

Upvotes: 3

Views: 28259

Answers (4)

Dalio Braga
Dalio Braga

Reputation: 1

When response.data == [], this works:

if (response.data.length === 0)

This is a Array then has length prospriety.

Upvotes: 0

andreapier
andreapier

Reputation: 2958

Your JSON:

{"1":{"id":"1","name":"Plymouth"},"2":{"id":"2","name":"Torquay"}}

is an object, not an array so the length property is not defined. If you want to parse it as an array your server needs to give a response like:

{"response": [{"1":{"id":"1","name":"Plymouth"}},
{"2":{"id":"2","name":"Torquay"}}] }

with [] instead of {}

Upvotes: 2

adeneo
adeneo

Reputation: 318222

Probably not the best way of doing this, but something like this could probably be a quick fix?

$('.locationList').empty();
$('.locationList').append('<option value="">Select...</option>');
$.getJSON('/Settings/locations.txt', function (data) {
    var dataNum = 0;
    for (i in data) {if (data.hasOwnProperty(i)) {dataNum++;}}    
    var counter = 1;
    $.each(data, function (i, item) {
        $('.locationList').append('<option value="' + data[i].id + '">' + data[i].name + '</option>');
        if (counter >= dataNum) {
            $('#bookTo').val(locationID + 1);
            $('#transferFrom').val(locationID);
        };
        counter++;
    });
});

Upvotes: 3

Andreas Louv
Andreas Louv

Reputation: 47099

This is an object:

data = {
    "1": {
        "id": "1",
        "name": "Plymouth"
    },
    "2": {
        "id": "2",
        "name": "Torquay"
    }
}

and it doesn't have a length property.

see: only the property 1 and 2.

Are you sure you want it as an object rater then an array:

data = [
    {
        "id": "1",
        "name": "Plymouth"
    },
    {
        "id": "2",
        "name": "Torquay"
    }
]

then you have the length property and a lot of other native array methods like sort. And you can access your data like this:

data[0]

witch is equal to:

{
    "id": "1",
    "name": "Plymouth"
}

Upvotes: 4

Related Questions