I have the following code I've designed to load and run script at runtime. You'll note that I save it to localStorage if it isn't already there. Now it runs fine if it's stored there already, but when it's just got the text from the file it throws ReferenceError: loginLaunch is not defined
, though the text seems to have been loaded (hence the console.log
lines that check the length). For your convenience I've included a line, localStorage.clear();
, to make it alternate between the error message that's the problem and ReferenceError: loginLaunch is not defined
, which given the code below is the desired result.
I don't understand why it should work one way and not the other. If it's a timing issue I don't see how the use of the promise, loginCode
, lets it through unless possibly appendChild()
is asynchronous, but I'm under the impression that it isn't (mainly because it has no callback, and I tried to find out, but could not) and even then why would code before the appendChild()
have an impact?
Have I messed up one of the promises? I include the contents of the file login.js at the end. I searched SO for anything relevant but without any luck except for just one post that states that appendChild
is synchronous.
Please help.
var loginCode = runCode("login_1001","./js/login.js");
loginCode.done(loginLaunch());
//FUNCTIONS START HERE
function getCode(local, source) { //This creates the promise to get the code (not to run it)
console.log("start of loadCode");
dfd = $.Deferred(); //This is the one to return.
script = localStorage.getItem(local); //Try to load from local storage.
// console.log("script after local attempt: "+script);
if (script) { //If found...
console.log("found Local code");
dfd.resolve(script);
localStorage.clear(); //Added for debugging
} else { //load from file.
ajax = $.ajax({
url : source,
cache : false,
dataType : "text", //load as text initially so that we can store it locally.
});
ajax.done(function(fromFile){
localStorage.setItem(local, fromFile); //store it locally.
//console.log("script after ajax attempt: "+script);
dfd.resolve(fromFile);
});
ajax.fail(function(){
dfd.reject("Error retrieving code. You may be disconnected");
});
}
return dfd.promise();
}
function runCode(local, source) {
dfd = $.Deferred(); //This is the one to return.
code = getCode(local, source); //local promise
code.done(function(retrievedCode){
console.log(retrievedCode.length);
var head = document.getElementsByTagName('head')[0]; //first head section
var el = document.createElement("script"); //named the same as the local storage
//script.type= 'text/javascript'; Redundant — it's the default
// el.id = local; //Probably redundant, but if we want to manipulate it later...
el.text = retrievedCode;
head.appendChild(el); //This shouldn't run anything, just make global functions that will be called later.
console.log(el.text.length);
dfd.resolve(); //If we need to return the node to manipulate it later we'd make the variable above and 'return' it here
});
return dfd.promise();
}
Here's the contents of the login.js file.
function loginLaunch(){
dfd = $.Deferred(); //This is the one to return.
loadElement("login.1001", "#content", "login.html");
//After the element has been loaded we have a disconnect — i.e. there's no promise waiting, so we have to wait for the user.
}
$("#content").delegate('#loginButton','click',function(){
console.log("Login click");
//php to pick up the entered details and pass them to common php that also uses the
checkCredentials = $.ajax({
type : "POST",
url : "./php/credentials.php",
data : {
queryString : queryString
},
datatype : "text", // 1 or 0
});
checkCredentials.done(credentialsChecked(success));
// MOVE THIS STUFF
readyPublicList();
$.when(publicListCode,loggedIn).then(runDefaultPublicList()); //Assumes successful login so it loads the code for the list window in parallel.
//Note that it's probable that my approach to the login window may change, because it needs to be available on the fly too.
// $("#content").html("<p>test</p>"); //Successfully tested, well it was once.
});
function loginHide(){
$("#loginHtml").hide;
}