0

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.

4
  • Thank you everyone, I see where the problem is and I made some changes. But it turns out, I cannot do initBuffers in the function loadXMLDoc() because I use webgl to draw something, and the buffers should be in the same process. If I put initBuffers in loadXMLDoc(), webgl cannot access to them. Any thoughts? Commented Apr 6, 2013 at 16:23
  • 1
    please give more details. what happens when you put initBuffers inside the handler? what do you mean 'webgl cannot access them'? your code is executed in the same process, there is no other process, is there? is this inside a web browser? Commented Apr 6, 2013 at 17:35
  • Thank you @akonsu, I figure out I need a call back to know that, loadXMLDoc() is completed, than I do initBuffers. I think that's a good way to solve my problem. There are three status: request_send, request_process, request_done. So after request_done, I can do initBuffers out of the function loadXMLDoc(), is that correct? Commented Apr 9, 2013 at 13:18
  • yes, that is correct. you can call initBuffers from inside your anonymous function that you assign to the onreadystatechange property. Commented Apr 9, 2013 at 14:36

4 Answers 4

2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, but do you know any ways to pass the obj out of function?
0

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.

Comments

0

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.

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.