Aaron
Aaron

Reputation: 1583

(js) Firebug debug causing code to work

Please excuse the awkward title I'll try my best to explain my peculiar problem.

I have three bits of javascript code:

What should be noted is that the self executing code and the callback function are defined within their own closure. The ajax function is accessed through an imported named closure which I defined as $.

I am fairly new to JavaScript and I am still learning about closures and their scopes. I have reason to believe that this problem is probably related to that.

Anyway, my problem relates to trying to access that supposedly populated array. Since I defined the array in a suitable scope (or so I believe) as the parse function I think I should have no problem pushing items into it.

This is self exectuting :

(function ($){

    //Load stock
var items = [];
var response = $.Ajax("scripts/Lookup.php","GET",parse);

function parse(a){
    for(/*Simplified view*/){
        var item = new $.Item();
        item.name = domStuff.textContent;
        item.description = domStuff.textContent;
        item.price = domStuff.textContent;
        item.id = domStuff.textContent;

        items.push(item);
    }
}

    //Test the length (and verify contents)
    for(var i=0; i < items.length; i++){
        alert(items[i].price);
    }
}($));

This is my definitions, which includes the Ajax function:

var $ = (function(){
var s = {};

    var ajax = function(url,method,callback){
        var a = new XMLHttpRequest();
        a.open(method, url, true);
        a.onreadystatechange = function(){
        if(this.readyState==4){
                callback(a);
            }
    }
    a.send();
    };

    s.Ajax = (function(){
        return ajax;
    }());

return s;
}());

So what justifies the title is that when I probe the code with firebug, I can see that items is populated with 3 Objects correctly defined by the parsed data.

The loop then alerts as intended 3 times.

However, if I remove the break points and have firebug ignore the code then the loop doesn't play out and I can only assume that the array is empty.

The code works also if I alert(items) prior to the test loop.

Upvotes: 0

Views: 721

Answers (3)

Paul Perigny
Paul Perigny

Reputation: 973

Your parse function is called asynchronously. You need to wait for the parse function to be called before testing it.

Either test the result in you parse function or have another function as the callback for ajax call. This function calls parse and then test the results.

Upvotes: 1

geoffrobinson
geoffrobinson

Reputation: 1580

I'm not a JavaScript expert by any means. However, I have run into situations on other programming languages where debugging has solved an issue.

In those cases, debugging has slowed the code down enough for it to work. Some process A needs asynchronous process B to return an object or do something before executing beyond a certain point. What is most likely happening in these types of scenarios is that the main thread is continuing or not waiting for the object to be populated by the other routine.

I hope that helps.

Upvotes: 1

Rudu
Rudu

Reputation: 15892

AJAX is filling items asynchronously, meaning in your closure, on first execution items.length will be zero (from the original array initialization). Over time, AJAX through calls to your parse method will fill this array.

Because you're keeping items in a closure, you won't actually be able to access it from outside - which is a good practice, but can cause problems with debugging! Instead of items.push(item) try alert(item) (any browser, but execution blocking) or console.log(item) (firebug only) to see that you are, indeed, getting the results back from AJAX just not in initial execution.

Upvotes: 2

Related Questions