Lamloumi Afif Lamloumi Afif - 3 years ago 149
HTML Question

Avoiding multiple load of javascript file

I add this snippet to each javascript file used in my asp.net web api application to avoid multiple load :

Fullcalendar.js

blog = {};
blog.comments = blog.comments || {};
blog.comments.debugMode = false;

blog.isFirstLoad = function (namesp, jsFile) {
var isFirst = namesp.jsFile.firstLoad === undefined;
namesp.jsFile.firstLoad = false;
return isFirst;
};

$(document).ready(function () {
if (!blog.isFirstLoad(blog.comments, "fullcalendar.js")) {
return;
}
});


Sometimes I get a weird exception


Uncaught TypeError: Cannot read property 'firstLoad' of undefined


I need to know :


  1. Why this happens?

  2. How can I fix it?


Answer Source

A couple of problems there.

First, you shouldn't be loading the file more than once in the first place, so it shouldn't be necessary to go through this business of trying to figure out whether you've loaded it.

But if you want to do that:

The first practical issue is that you're always doing this:

blog = {};

...which means if there's already a blog global, you're wiping out its value and replacing it with an empty object. If you want to use an existing global's value or create a new one, do this:

var blog = blog || {};

That seems odd, but since repeated var declarations are fine (and don't change the variable), that will use an existing one's value, or if there isn't one (or its value is falsey) it will create a new one and initialize it with {}.

Then, the line

namesp.jsFile.firstLoad = false;

...looks for a property called jsFile on namesp and assumes it's not null or undefined. It doesn't look for a property using the jsFile argument's value.

To do that, use brackets notation:

namesp[jsFile].firstLoad = false;

Even then, though, you're assuming it's not null or undefined, but it may well be. You probably just wanted:

namesp[jsFile] = false;

Or possibly:

namesp[jsFile] = namesp[jsFile] ||{};
namesp[jsFile].firstLoad = false;

That said, it seems really odd to use blog.comments to track whether JavaScript files have been loaded. If the file may have already been loaded, just this will do it:

var fullCalendarLoaded;
if (fullCalendarLoaded) {
    // It's already loaded
} else {
    // It isn't, but it is now
    fullCalendarLoaded = true;
    // ...do your init...
}

Or if you have several of these and want to use a single global for it:

var loadedScripts = loadedScripts || {};
if (loadedScripts.fullCalendar) {
    // Already loaded
} else {
    // Not loaded yet
    loadedScripts.fullCalendar = true;
    // ...do init...
}

Or if using the filename is important:

var loadedScripts = loadedScripts || {};
function firstLoad(filename) {
    if (loadedScripts[filename[) {
        return false;
    }
    // Not loaded yet, remember we've loaded it now
    loadedScripts[filename] = true;
    return true;
}

Then:

if (firstLoad("fullcalendar.js")) {
    // First load, do init...
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download