Reputation: 3
I'm trying to set a JSON object from a Javascript function and use it as parameter in another function, but this obj has no value outside the function. I created this json object outside the function:
var obj = {"Level":0, "Index":0, "Count":0, "AABB":[], "Point":[], "Children":[]};
Then
function loadXMLDoc()
{
if(window.XMLHttpRequest){
xmlhttp=new XMLHttpRequest();
} else {
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function(){
if(xmlhttp.readyState==4 && xmlhttp.status==200){
var string = xmlhttp.responseText;
obj = JSON.parse(string);
document.getElementById("myDiv").innerHTML = obj.Children;
}
}
xmlhttp.open("GET","r0.json",true);
xmlhttp.send();
return obj;
}
but after I call the function and pass the obj, like this:
var obj = loadXMLDoc();
initGL(canvas);
initShaders();
initBuffers(obj);
It cannot pass the value to function initBuffers. Why did that happen and how can I solve that? Thanks.
Upvotes: 0
Views: 937
Reputation: 225
Variables inside functions are bound to that particular function and can not be reached from outside the function unless they are within the function containing the variable or if the variable is set to be global.
If its only a few objects a dirty way is to create a span that you use a global container.
Upvotes: 0
Reputation: 1407
like @akonsu said's the return of your loadXMLDoc function is called before the ajax call finish because that call is asynchronous so when you do an ajax there is created another process with that call, then the current process (with the function loadXMLDoc) works unconcerned, only the code inside the onreadystatechange function is called when the call ends, so i suggest to you to create a function callback that executes the code inside the ajax onreadystatechange like this:
function loadXMLDoc()
{
if(window.XMLHttpRequest){
xmlhttp=new XMLHttpRequest();
} else {
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function(){
if(xmlhttp.readyState==4 && xmlhttp.status==200){
var string = xmlhttp.responseText;
var obj = JSON.parse(string);
document.getElementById("myDiv").innerHTML = obj.Children;
SOME_CALLBACK(obj)
}
}
xmlhttp.open("GET","r0.json",true);
xmlhttp.send();
//return obj; no needed any more
}
function SOME_CALLBACK(obj){
initGL(canvas);
initShaders();
initBuffers(obj);
}
So this way the SAVE_CALLBACK function receives the asynchronous obj data and works with these.
Upvotes: 0
Reputation: 14219
Because of what @akonsu said (synchronous nature of onreadystatechange
), loadXMLDoc()
will still be running when your init functions are run. As a result your obj
variable will not yet be defined when initBuffers(obj)
is run.
A simple solution is to add a callback to loadXMLDoc()
:
function loadXMLDoc(objParsed)
{
...
xmlhttp.onreadystatechange=function(){
if(xmlhttp.readyState==4 && xmlhttp.status==200){
var string = xmlhttp.responseText;
obj = JSON.parse(string);
document.getElementById("myDiv").innerHTML = obj.Children;
objParsed(obj);
}
}
xmlhttp.open("GET","r0.json",true);
xmlhttp.send();
}
and use it like this (assuming initGL()
and initShaders()
don't rely on the result of initBuffers()
):
loadXMLDoc(initBuffers);
initGL(canvas);
initShaders();
And as an aside, you appear to be changing the value of obj
:
obj = JSON.parse(string);
So when you later try and access obj.Children
it won't exist unless your xmlhttp.responseText
is valid JSON and has a Children
property off the root. It will also completely overwrite the value you set at the top of your script.
Upvotes: 0
Reputation: 29538
I am not sure what you mean when you say that you cannot pass obj
as a parameter, but one thing to realize is that your onreadystatechange
handler is called asynchronously, after you call initBuffers
. Perhaps, you need to call your initialization routines from inside the handler, when the JSON response is parsed.
Upvotes: 2