0

I tried to run this but it doesn't work. It is intended to return a variable assigned inside a function, that was passed as callback to sendRequest(), which is retrieving data from the Internet through XMLHttpRequest asynchronously.

Can anyone tell me why this is not working and always returning ""?

function sendRequest(requestCode, args, callback){
 var req = requestEngineUrl + "?req=" + requestCode + ";" + args;
 var xmlHttp = new XMLHttpRequest();
 xmlHttp.onreadystatechange = function(){
  if(xmlHttp.readyState == 4)
  { 
   if(callback != null){
    callback(xmlHttp.responseText);
   }
  }
 };
 xmlHttp.open("GET", req, true);
 xmlHttp.send(null);
}

this.assembleProcess = function(){
  if(!isNull(this.id) && !isNull(this.titles)){
   var titles = this.titles;
   var id = this.id;
   c = "";
   sendRequest('304', id, 
    function(result){
     var res = result.split("/");
     var title = res[0];
     var possibilities = res[1];
     var fcontent = title + '<br><div>';
      if(titles.length != possibilities){
       console.log("WARNING: [SURVEYCARD].titles has not the same length as possibilities");
      }
     
      for(i = 0; i < possibilities; i++){
       fcontent += '<div><a onclick="sendRequest("301",' + id + ',' + i + ',null)">' + titles[i] + '</a></div>';
      }
     
     fcontent += '</div>';
     c = fcontent;
    });
   return c;
  } 
aprofomo
  • 3
  • 3
  • 2
    The process is **asynchronous**. The callback function you send to the `sendRequest()` function will be invoked at the time the HTTP request completes. The `alert(c)` statement is reached *long* before that time. – Pointy Jul 12 '15 at 21:42
  • Is there a way to do it either? – aprofomo Jul 12 '15 at 21:57
  • Yes - you're passing in a callback function already. When the callback runs, the content will be available, and you can do whatever work you need to do there. That's the nature of programming with callbacks in an asynchronous environment. – Pointy Jul 12 '15 at 21:58
  • Edited - new question – aprofomo Jul 12 '15 at 22:00
  • [You cannot return values from asynchronous operations.](http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-asynchronous-call) – Pointy Jul 12 '15 at 22:17

1 Answers1

1

As an XMLHttpRequest is async, you should write an async function for that matter, like this

this.assembleProcess = function(callback){
        if(!isNull(this.id) && !isNull(this.titles)){
            var titles = this.titles;
            var id = this.id;
            c = "";
            sendRequest('304', id, 
                function(result){
                    var res = result.split("/");
                    var title = res[0];
                    var possibilities = res[1];
                    var fcontent = title + '<br><div>';
                        if(titles.length != possibilities){
                            console.log("WARNING: [SURVEYCARD].titles has not the same length as possibilities");
                        }

                        for(i = 0; i < possibilities; i++){
                            fcontent += '<div><a onclick="sendRequest("301",' + id + ',' + i + ',null)">' + titles[i] + '</a></div>';
                        }

                    fcontent += '</div>';
                    c = fcontent;
                    callback(c)
                });
        } 

and then, instead of using this.assembleProcess as a function with a result, you should pass a function as parameter:

Instead of

console.log(this.assembleProcess);

do this

this.assembleProcess(function(c){console.log(c)});
jperelli
  • 6,988
  • 5
  • 50
  • 85