Geert Kamps
Geert Kamps

Reputation: 53

getScript creates ReferenceError

I have some js scripts that I load into my main.js before I start the rest of my code. However during testing it came to my attention that sometimes it creates the following reference error (1 in 8 pageloads or something).

ReferenceError: createContainer is not defined

Now, the only reason that I can think of that I get this error is that when I execute the startScript() function, not all my files are loaded or fully accesable.

Now, perhaps I'm going about this all wrong for including other .js files into my main.js, so I'd like to hear your thoughts about this.

The main.js looks like this:

$(document).ready(function() {

    //sets and array of files that should be loaded before anything every happens
    var arrFilesToLoad = [  'scripts/global/variables.js',
                            'scripts/global/objects.js',
                            'scripts/global/classes.js'];
    var _error;

    //walks through the array of items that should be loaded and checks for fails
    $.each(arrFilesToLoad , function (key) {
        $.getScript(arrFilesToLoad[key])
            //when a file is loaded with succes
            .done(function () {
                //on default send a message to the console
                console.log(arrFilesToLoad[key] + 'loaded succesfully');
                //if every item is loaded start the script
                if(key == (arrFilesToLoad.length - 1)){
                    startScript();
                }
            })
            //when a file fails to load
            .fail(function () {
                //add the file that failed to load to a string message
                _error += arrFilesToLoad[key] + " - failed to load. \n";
                //show an alert with what file failed to load
                if(key == (arrFilesToLoad.length - 1)){
                    alert(_error);
                }
            });
    });

    function startScript () {
        //set a variable which contains a function that returns a DIV with styling
        var oContainer = createContainer();
        var oMainMenu = new Menu(arrMainMenu);
        $(oContainer).append(createMenu(oMainMenu));
        $('body').append(oContainer);
    }

});

Upvotes: 4

Views: 705

Answers (1)

Rory McCrossan
Rory McCrossan

Reputation: 337627

The issue is because you're loading 3 scripts and presumably only one of them holds the createContainer() function, yet you execute your code when the last request has loaded. This means that you've got a race condition. The last request that was made is not guaranteed to be the last one that is completed. If the other scripts are still being loaded as the final request is completed, you'll see this error.

You can amend your logic so that the callback is only executed once all the scripts have loaded. Try this:

var requests = [];
$.each(arrFilesToLoad , function (key) {
    requests.push($.getScript(arrFilesToLoad[key]));
});

$.when.apply(this, requests)
    .done(startScript)
    .fail(function() {
        console.log('one or more scripts failed to load');
    });

function startScript() {
    var oContainer = createContainer();
    var oMainMenu = new Menu(arrMainMenu);
    $(oContainer).append(createMenu(oMainMenu));
    $('body').append(oContainer);
}

Upvotes: 4

Related Questions