Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Object length is 0, but there are several items within it

Tags:

javascript

I'm creating an object (dataObj) that returns several items within it, inside a $getJSON:

var cities = ['london', 'paris', 'munich', 'geneva', 'prague', 'vienna', 'barcelona', 'istanbul'],
    totalCities = cities.length,
    i = 0,
    $container = $('#cities'),
    htmlFragment,
    data,
    obj,
    dataObj = {
        cities:[]
    };

function appendData() {

    var city = cities[i],
        locationQuery = escape("select item from weather.forecast where woeid in (select woeid from geo.places where text='" + city + "') and u='c'"),
        locationUrl = "https://query.yahooapis.com/v1/public/yql?q=" + locationQuery + "&format=json&callback=?";

    if ( i === cities.length ) { return };

    $.getJSON( locationUrl, function( data ) {
        var condition = data.query.results.channel[0].item.condition.text,
            temperature = data.query.results.channel[0].item.condition.temp;

        obj = {
            city: city,
            condition: condition,
            temperature: temperature
        };

            dataObj.cities.push(obj);

        // $container.append(html);

        appendData();

    });

    i = i + 1;
}

appendData();

var source   = $("#some-template").html();
var template = Handlebars.compile(source);

var dataObjExample = { cities: [
        {city: "london", condition: "Cloudy", temperature: "8" },
        {city: "paris", condition: "sunny", temperature: "5" },
        {city: "munich", condition: "Rainy", temperature: "3" }
    ]};

console.log(dataObj);
console.log('dataObj:' + dataObj.cities.length);

console.log(dataObjExample);
console.log('dataObjExample:' + dataObjExample.cities.length);

$("#content-placeholder").html(template( dataObj ));

When I console.log the dataObj.cities it all looks fine and there are lots of items, however the length is at 0, which I'm sure is the source of my problems. I've been fiddling around and searching for some time for a solution, with no avail. Any ideas clever people?

update

Apologies, in my delirious state last night I meant to write: dataObj.cities.

I've added 2 console.logs to the JS. One is the real data and shows the length of dataObj.cities.length as 0. The other is where the object is created manually and displays dataObjExample.cities.length correctly as 3.

Please view the console at this url: https://dl.dropboxusercontent.com/u/36374911/weather%20app/index.html

Thanks in advance!

like image 205
DanV Avatar asked Jan 23 '14 23:01

DanV


2 Answers

Plain objects like your "dataObj" don't have a .length property (unless you make/maintain one). That's an array thing, and it only works with numerically-indexed properties.

Now, dataObj.cities.length will give you the length of that array.

like image 128
Pointy Avatar answered Oct 12 '22 23:10

Pointy


The 'appendData' function is a recursive function which doesn't work in the same way as a for loop would.

When i === cities.length invoke another function which will have access your your completed array.

$(document).ready( function () {

var cities = ['london', 'paris', 'munich', 'geneva', 'prague', 'vienna', 'barcelona', 'istanbul'],
    totalCities = cities.length,
    i = 0,
    $container = $('#cities'),
    htmlFragment,
    data,
    obj,
    dataObj = {
        cities:[]
    };

function appendData() {

    var city = cities[i],
        locationQuery = escape("select item from weather.forecast where woeid in (select woeid from geo.places where text='" + city + "') and u='c'"),
        locationUrl = "https://query.yahooapis.com/v1/public/yql?q=" + locationQuery + "&format=json&callback=?";

    if ( i === cities.length ) { 
        buildTemplate();
        return;
    };

    $.getJSON( locationUrl, function( data ) {
        var condition = data.query.results.channel[0].item.condition.text,
            temperature = data.query.results.channel[0].item.condition.temp;

        obj = {
            city: city,
            condition: condition,
            temperature: temperature
        };

        dataObj.cities.push(obj);

        appendData();
    });

    i = i + 1;
}

function buildTemplate() {
    var source   = $("#some-template").html();
    var template = Handlebars.compile(source);

    var dataObjExample = { cities: [
            {city: "london", condition: "Cloudy", temperature: "8" },
            {city: "paris", condition: "sunny", temperature: "5" },
            {city: "munich", condition: "Rainy", temperature: "3" }
        ]};

    console.log(dataObj);
    console.log('dataObj:' + dataObj.cities.length);

    console.log(dataObjExample);
    console.log('dataObjExample:' + dataObjExample.cities.length);

    $("#content-placeholder").html(template( dataObj ));
}

appendData();

});

like image 38
Lewis Coulson Avatar answered Oct 12 '22 22:10

Lewis Coulson