A variable that I've initialized is undefined when I try to use it on the next line of code

I'm developing a web application that is heavily using Javascript and jQuery.

I basically create an app object when the web page loads and call the init() method in the footer.

var app = new App();
app.init();

These are the first lines of code in the init() method.

// Load up the index
app.loadIndex();

alert(hashtag_index);

These are a few lines of the loadIndex() method.

hashtag_index  = [];

// Load the Topic JSON File
$.ajax({
    url : './data/index.json',

    type : 'GET',

    dataType : 'json',

    .
    .
    .

    // If the file loading is successful, save the index data
    success : function(data){

    var raw_index = [];

    $.each(data, function(key, val) {
        raw_index.push(data[key]);
    });

    // Add the hashtag object to global hashtag_index
    hashtag_index = raw_index;

    }
});

Basically what the loadIndex() method does is loads a json file which is about 135kb and load the data as an object to the hashtag_index variable. The hashtag_index variable is defined global, so it's accessible globally.

The variable hashtag index have 8 different Object arrays. But during when I try to alert() the variable, the variable isn't initialized yet.

But alert() only returns an blank message. When I return this as an message:

alert(typeof(hashtag_index))

I get undefined as the message.

But now I'm sure the variable is loaded because, when I access the variable via Google Chrome's console, I can see the variable is loaded up and all the objects are in there.

The only was I solved the problem was by using this line of code:

// Load up the index
app.loadIndex();

setTimeout( function(){

    alert(hashtag_index);

}, 500);

By making javascript sleep 500 ms, I've given enough time for it to load up.

Of course I've tried the following solutions but none of them succeeded:

Solution 1: (Goes into an infinite loop)

// Load up the index
app.loadIndex();

while(!hashtag_index.length > 0) {

    continue;

};

alert(hashtag_index);

Solution 2: (Goes into an infinite loop)

// Load up the index
app.loadIndex();

while(hashtag_index.length == 0) {

    continue;

};

alert(hashtag_index);

Solution 3: (Goes into an infinite loop)

// Load up the index
app.loadIndex();

while(typeof hashtag_index === 'undefined') {

    continue;

};

alert(hashtag_index);

Solution 4:* (Goes into an infinite loop)

// Load up the index
app.loadIndex();


while(typeof hashtag_index == null) {

    continue;

};

alert(hashtag_index);

Now my question is how can I solve this problem definitely without causing any future problems. I've tried to tackle the problem with the previous solutions, but none of them have succeeded properly.

Upvotes: 1

Views: 91

Answers (1)

Jason P
Jason P

Reputation: 27012

Your app.loadIndex(); method uses ajax, which is async. So the alert(hashtag_index); executes before the ajax call has completed and the result is processed.

Change your code to use a callback, or (my preference) have app.loadIndex(); return a promise object.

Here's how you could implement a promise:

var loadIndex = function() {
    var def = $.Deferred();

    $.ajax({
        //...
        success: function(result) {
            // do whatever
            def.resolve();
        }
        //...
    });   

    return def.promise();
};

....

// Load up the index
app.loadIndex().done(function() {
    alert(hashtag_index);
});

You may need to extend this to have init() return a promise or accept a "finished" callback as well, depending on your usage.

Upvotes: 6

Related Questions