views:

894

answers:

4

Hello,

I'm using the following bit of script to load another one:

$.getScript("CAGScript.js", function () {
    try {
        CAGinit();
    } catch(err) {
        console.log(err);
    }
});

The idea is that $.getScript loads the script, then executes the callback when it's done. CAGInit() is a function that lives in CAGScript.js.

The problem is that roughly half the time, CAGInit() doesn't fire (in any browser). Logging to the Firebug console reports that it's not defined. The rest of the time it works perfectly.

Does anyone have any ideas what I'm doing wrong?

Thanks.

+1  A: 

I think you can start by checking testStatus of the callback function to make sure that the script was really loaded. Callback function has two parameters, more defails on those you can find on jQuery Docs

$.getScript("CAGScript.js", function (data, textStatus) {
    if (textStatus === "success") {
        try {
            CAGinit();
        } catch(err) {
            console.log(err);
        }
    } else {
        console.log("script not loaded");
    }
});
RaYell
I thought this had fixed it, but I'm still occasionally seeing "ReferenceError: CAGinit is not defined" even when textstatus === "success". I'll give J-P's non-XHR solution a go.
Olly Hodgson
+3  A: 

If the file is held on the same domain then jQuery will use XHR to retrieve its contents and then will globally "eval" it. This should work fine but if you're having problems then I'd suggest using the alternative method of injecting a script tag. Unfortunately, jQuery doesn't expose this functionality so you'll have to do it yourself:

var script = jQuery('<script/>').attr('src', 'CAGSCript.js').appendTo('head');

var timer = setInterval( function(){ 
    if (window.CAGInit !== undefined) {
        clearInterval(timer);
        script.remove();
        // Do your stuff:
        CAGInit();
    }
}, 200);

It'd be best to abstract this to a function; the above is just an example...

J-P
This one seems to have done the trick, thanks :)
Olly Hodgson
+1  A: 

Hi Olly

Just had the same problem on firefox, solved it with a little hack.

Applying it to your example:

$.getScript("CAGScript.js", function (xhr) {
    try {
        CAGinit();
    } catch(err) {
        eval(xhr);
        CAGinit();
    }
});

Basically forcing an evaluation of the XHR response if it fails to do so by itself.

Pieter
Fantastic, thanks. I'll give it a try next time I need to load a script :)
Olly Hodgson
+1  A: 

Yeah, I've discovered too that getScript is unreliable in FireFox, firing the callback before the script has been downloaded and/or executed. (Using JQuery 1.41 & FireFox 3.6. Issue doesn't seem to afflict IE, Chrome or Opera.)

I haven't done extensive testing, but it seems to only happen with some specific scripts...not sure why.

RaYell's suggestion doesn't work, as getScript will report success even though the script has not yet been eval'ed. Pieter's suggestion in most cases causes the code to be eval'ed twice, which is inefficient and can cause errors.

This alternative seems to work where getScript does not. Note that it seems to be adding a SCRIPT DOM element, whereas getScript does XHR.

http://www.diveintojavascript.com/projects/sidjs-load-javascript-and-stylesheets-on-demand

capnhairdo
Yep, that's pretty much how J-P's answer above works :)
Olly Hodgson