views:

184

answers:

4

I am loading a JS file needed only for one part of my web page, only when the user navigates to that tab on the page.

var scriptFile = document.createElement("script");
scriptFile.setAttribute("type", "text/javascript");
scriptFile.setAttribute("src", scriptURL);

I am trying to come up with an error handling mechanism for this dynamic loading, so that I can show an error message if the JS load times out or if the JS is unavailable in the location specified by the URL.

This is how I am trying to implement the error handling (for IE):

scriptFile.onreadystatechange = function() { // For IE
    if (this.readyState == 'complete' || this.readyState == 'loaded') {
        // Display content in tab
    } else {
        // Display error message
    }
}

This is causing one problem. When all is fine, and the JS is present as expected, I am getting the error message first, and then the correct content.

After some brainstorming, I found out that the readyState changes from "uninitialized" to "loading" first, and then to "loaded". Its when the state is at "loading" that the error message is being displayed. After that, the state is changing to "loaded" at which point the content is being displayed.

Any ideas how to handle this so the error is not displayed initially?

+1  A: 

what about having one (global) variable to check if it's loaded (e.g. the script will set it after loading finished) and then have another function (already on the page before the loading function) set with timer to check for that variable (e.g. 5 seconds delay?)

if the variable is not set (after the predefined amount of time), display error to the user.

dusoft
Hmm.. sounds good. I'll give it a try.
Phanindra K
But this means you only allow 5 seconds to load the script; once they've passed if it's still loding you still display the error message. What if the user's modem is heavily loaded due to heavy streaming of hardcore porn or an extremely high number of requests for lolcats?
Kaze no Koe
you can make it 10, whatever :-)
dusoft
Lolcats can be very heavy, you know. They eat a lot of cheezburgerz. Seriously, I disagree. I think a fixed timeout is wrong.
Kaze no Koe
i understand your concern, but as you say above, there is no other solution, so this is just a kind of workaround.
dusoft
+1  A: 

I think you need to scrap the "else", as it will always go through that "loaded" state, whether it's going to work or not, so the "else" branch isn't doing anything useful.

Instead, set a timeout.

var scriptTimer = setTimeout(function() {
  // show error message
  // (should ideally precede with a check the content hasn't
  // been displayed, in case of race condition)
});
scriptFile.onreadystatechange = function() { // For IE
    if (this.readyState == 'complete' || this.readyState == 'loaded') {
       clearTimeout(scriptTimer);
       // now display content in tab
    }
}
mahemoff
What happens if even after the timeout, the script does not load?How do I handle that?
Phanindra K
You've shown the error message; there's nothing else to handle. If you want, you could try a few more times, ie start with a counter "var scriptAttempts = 3", and try loading the script again from the setTimeout handler. Each time you run the function to load the scrpt, it checks if scriptAttempts > 0, and decrements scriptAttempts, until giving up and showing the error message. I would also show a progress indicator if you were doing all this as the delay might be quite long.
mahemoff
+2  A: 

Since there is no "oops I died!" state, you can't display error messages.

edit: removed the code since my point is that you can't do that. With an AJAX request you can check the response and see if it's a 404 but you can't do that with a script tag.

edit2: on second thought, why don't you fetch the script via AJAX and inject a '<script type="text/javascript">' + responseText + '</script>' inside document.body?

To check if an AJAX request has bombed, check the XMLHTTPRequest object's status property. If it's 404, well, it's a 404.

Also, you shouldn't do this stuff by hand. I always suggest using Prototype or jQuery. Since I have been spoiled by Prototype, I shouldn't try to explain how to check for the request's status. Why don't you ask how to handle AJAX requests in another question here? The pros will certainly tell you how to handle all kinds of failures, not just 404.

Kaze no Koe
Hehe.. the whole point of my exercise is to display the error messages. :)
Phanindra K
I know, but you can't tell if the script has failed. At least my version doesn't give up after the first time the object changes state.
Kaze no Koe
Pls check my update.. I need to handle the case where the JS didn't load at all too (HTTP 404).
Phanindra K
Ok, so I load the content of the JS using an AJAX call and load it the document body, huh? Worth a try.Sorry for being an AJAX noob, but how do you check there if the status is a 404?
Phanindra K
You check the response headers. Let me search for some docs you can use.
Kaze no Koe
I'm using Dojo, actually. Have to explore a little using that.Doumo arigatou gozaimashita, Kaze-san!
Phanindra K
Dou itashimashite!
Kaze no Koe
A: 

EDIT: my method was wrong - use AJAX as Kaze suggested

Amarghosh
If it's not "complete" or "loaded", how could it NOT be "loading"?
Kaze no Koe
Since he was displaying error message in the else part, I assumed there would be some 'error' state that he was looking for - googled and found that it doesn't work that way. Loading thru AJAX and checking for 404 is the way to go I guess.
Amarghosh