1

I have the following script which is not working for some reason:

success: function( widget_data ) 
{ 

    if( widget_data.d[0] ) {

        var j = 0;

        for ( j = 0; j <= widget_data.d.length - 1; j++ ) {

            $.getScript( "js/" + widget_data.d[j].script, function() {

                // this line is complaining about .widget_id
                alert(widget_data.d[j].widget_id);
            });

            // but this line works fine...
            alert(widget_data.d[j].widget_id);

        }

    }

}

I get an error on the following line, with one withing .getScript:

alert(widget_data.d[j].widget_id);

The error message is:

Cannot read property 'widget_id' of undefined

But the strange thing is, the following alerts work fine and return the correct values:

alert(widget_data.d[j].widget_id);

What am I doing wrong?

oshirowanen
  • 15,297
  • 82
  • 198
  • 350
  • Can you show us html and is widget_header_ class? – Adil Nov 14 '12 at 16:50
  • Before I do that, I just tried the alerts within the `.getScript` and they stop working, they give the same error. As soon as I move the alerts out of `.getScript`, the alerts start working... – oshirowanen Nov 14 '12 at 16:53

1 Answers1

4

The getScript call runs asynchronously capturing the variable j not it's value at the time it is invoked. This means that j likely has the value that terminated the loop at the time the call returns. You should call the getScript within a function so you can capture the value of j rather than it's reference. Actually, it's probably better to actually capture the "widget" object itself, as you can see in the code sample.

success: function( widget_data ) 
{ 

    if( widget_data.d[0] ) {

        var j = 0;

        for ( j = 0; j <= widget_data.d.length - 1; j++ ) {

            getWidgetScript( widget_data.d[j] );

            alert(widget_data.d[j].script);

            // but this line works fine...
            alert(widget_data.d[j].widget_id);
            alert(widget_data.d[j].title);

        }

    }

}

function getWidgetScript(widget) {
    $.getScript( "js/" + widget.script, function() {
        $( ".widget_header_" + widget.widget_id ).text( widget.title );
    });
}
tvanfosson
  • 524,688
  • 99
  • 697
  • 795
  • Will this ensure that the script(s) load before the widget_id is used? – oshirowanen Nov 14 '12 at 16:57
  • @oshirowanen What will happen is that the widget object will be different for each function invocation. The `widget_id` will be that associated with the widget supplied as the parameter. Previously, it was attempting to use the value that `j` had when the asynchronous call returned not what it had when getScript was invoked. See this question: http://stackoverflow.com/questions/111102/how-do-javascript-closures-work – tvanfosson Nov 14 '12 at 17:10