Skip to content Skip to sidebar Skip to footer

Having Difficulty Working With Global Variables And $.getscript

I have the following script which does not work properly: function getWidgetContent( widget ) { if(widget.script!=null){ $global_widget_id = widget.widget_id; $

Solution 1:

You're getting this because $.getScript is an asynchronous method. In this case, it means that the method returns immediately before the script has finished loading, and continues executing code after it.

What this means is that something like:

$.getScript('a.js', function () {
    console.log('Loaded a');
    }); 
$.getScript('b.js', function () {
    console.log('Loaded b');
    }); 
$.getScript('c.js', function () {
    console.log('Loaded c');
    }); 
// Output could be:// Loaded c// Loaded a// Loaded b

This means that all of the script files requests can be done simultaneously but it also means that the order is not deterministic (fixed).

Use Promises

You can ensure that the getWidgetContent is called sequentially by chaining promises if you are using jQuery 1.5 and above. However, the pitfall of this method is that you will not be concurrently loading all the script requests at the same time, the requests will be sent one after another after the previous one has completed.

Make sure you return the result of $.getScript which is a Deferred Object (I made minimal changes here, just note the return statements):

functiongetWidgetContent( widget ) {
  if(widget.script!=null){
    $global_widget_id = widget.widget_id;
    return $.getScript( "js/" + widget.script, function() {
        $( ".widget_header_title_" + widget.widget_id ).append( widget.title );
        });
  }
  returnnull;
}

New method to perform a new getWidgetContent after a previous promise is fulfilled (completion of previous action):

functiondoGetWidgetContentAfter(promise, widget) {
  return promise.then(function () {
      returngetWidgetContent( widget );
      });
}

Calling it:

var promise = $.when(true);
for ( j = 0; j <= widget_data.d.length - 1; j++ ) {
  promise = doGetWidgetContentAfter( promise, widget_data.d[j] );
}

Explanation

What doGetWidgetContentAfter does is that when the said promise is complete then call the getWidgetContent function for widget. The then method returns a promise that completes when any internal methods promise completes.

I know it's starting to sound complicated, but do play around and experiment with it. :)

Solution 2:

Looking the others answers I can only think in do. Change the your implementation:

 $.getScript( "js/" + widget.script, function() {
     $( ".widget_header_title_" + widget.widget_id ).append( widget.title );
 });

To a corresponding ajax call, but not asynchronous

$.ajax({
  url: "js/" + widget.script,
  dataType: "script",
  async: false,
  success: function() {    
      $( ".widget_header_title_" + widget.widget_id ).append( widget.title );    
  }
});

Solution 3:

getWidgetContentis doing the getScript, but getScript returns immediately instead of waiting for the network (which is relatively slow compared to the CPU) to finish getting your script. This is not a bug, but an awesome thing - with asynchronous programming, you can get lots of work done on the CPU, and you don't have to wait for things that are much slower than the CPU if you don't want to!

To answer your question:

  • To set the global variable when the script request is done, simply move the variable assignment into your callback function.
  • Simply allowing all getScripts to run at once would be faster, but if you really can't allow a second getScript to start until the first finishes, call getWidgetContent just once, and have your callback determine the next widget in line and call getWidgetContent again with it.

Solution 4:

the getScript method is async, so before you get a response from the server containing youre script value the loop runs the next iteration thats why we have to send in a callback function. javascript knows what to do once the server responds. so while a normal loop cant help us here we can use a recusive function. what happens is thatwe get the callback function to call the loopFunc that then moves on to the next item in the collection/array. i hoppe this can give you som inspriation:

var getWidgetContent = function(wiget, loopFunc) {
  if(widget.script!=null){
    $global_widget_id = widget.widget_id
    $.getScript( "js/" + widget.script, function() {
        $( ".widget_header_title_" + widget.widget_id ).append( widget.title )
        loopFunc() //now we got a response from the server and want to move on to the next script tag.
    })
  }
}

var i = 0
(functionloopFunc(){ //we define a function and call it instantlyif(i < widget_data.d.length){ 
    getWidgetContent(widget_data.d,loopFunc) //now we call the getWidgetContent but we send in the current function aswellconsole.log($global_widget_id) // this is going to change each time
    i += 1
  }
}())

Solution 5:

Try assigning the variable to the window namespace:

window.global_widget_id = "foo";

You can then reference it like this:

var myId = window.global_widget_id;

and overwrite it:

window.global_widget_id = "newId";

(The $ in your variable assignment might be confusing jQuery too.) (Incorrect. Ignore that last part.)

EDIT:

It appears $.getScript() files aren't part of the global scope: jQuery's getScript - including files into the main scope?.

Maybe you could call the $.getScript() functions from a callback rather than an embedded document.ready(), and pass the variable through that way?

Post a Comment for "Having Difficulty Working With Global Variables And $.getscript"