1

I am a little confused why the console.log (at the bottom) returns the data as I expected, but the return optiondata does not.

function populate_selectbox()
{               
var ajaxRequest;

try {
    // Opera 8.0+, Firefox, Safari
    ajaxRequest = new XMLHttpRequest();
} catch (e) {
    // Internet Explorer Browsers
    try {
        ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
        try {
            ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
        } catch (e) {
        // Something went wrong
            alert("Your browser broke!");
            return false;
        }
    }
}

var queryString = "?callFunction=get_all_data";
//console.log(queryString);

ajaxRequest.open("GET", "php/shares.php" + queryString, true);
ajaxRequest.send(null);

var optiondata ="";

// Create a function that will receive data sent from the server
ajaxRequest.onreadystatechange = function() 
{

    if (ajaxRequest.readyState == 4 && ajaxRequest.status == 200) 
    {
        //console.log("IF....");

        var resp = JSON.parse(ajaxRequest.responseText);
        //console.log(resp)

        for (var i = 0; i < resp.data.length; i++) 
        {
            if(i === resp.data.length -1)
            {
                optiondata += "'"+resp.data[i].name+"'"; //For the last name in the loop
            }
            else
            {
                optiondata += "'"+resp.data[i].name+"',";
            }

        }

        console.log(optiondata); //This works
        return optiondata; //This returns undefines
    }    
};  
}

Question : Why is the result different?

jwknz
  • 6,598
  • 16
  • 72
  • 115
  • console is async, and that's not valid code... – dandavis Apr 14 '15 at 02:34
  • 1
    ok - so are you able to show me how to fix it? – jwknz Apr 14 '15 at 02:35
  • ok, seeing the whole code, if you want to return from that function, you need to set the 3rd arg to open() as false, but that's poor practice as it freezes the tab. it better to just call an action once you have the data, not call the data once you have an action. – dandavis Apr 14 '15 at 02:39

2 Answers2

0

You can't return any data from ajax callback using "return" keyword, because ajax request is asynchronous call.

Provide your own callback fn and pass results into it.

function myAjaxFn(..., done) {
    // ...
    xmlhttp.onreadystatechange=function()
      {
      if (xmlhttp.readyState==4 && xmlhttp.status==200)
        {
          done(xmlhttp.responseText);
        }
      }
    xmlhttp.open("GET","ajax_info.txt",true);
    xmlhttp.send();
}

Or use promises instead, e.g.: http://joseoncode.com/2011/09/26/a-walkthrough-jquery-deferred-and-promise/

vromanch
  • 939
  • 10
  • 22
  • so is done in the parameters a functions? - I appreciate jquery can do this easier, but I am wanting to get my head around the long way ;-) – jwknz Apr 14 '15 at 02:46
  • Yes `done` in this case should be a function. You could declare the `done` function outside and have it take a single parameter called `data` then log `data` to the console `function done (data) { console.log(data); }` – jasonscript Apr 14 '15 at 02:52
  • Ok I have tried a few things and when I have followed your example I get an error saying that done is not a function?? – jwknz Apr 14 '15 at 03:21
  • take a look here: http://jsfiddle.net/emersy/Lk5aqg45/ – vromanch Apr 15 '15 at 09:42
0

Try utilizing Promise object

    var queryString = "?callFunction=get_all_data";
    var request = function(queryString) {
      return new Promise(function(resolve, reject) {
        var ajaxRequest = new XMLHttpRequest()
        , optiondata = "";
        ajaxRequest.open("GET", "php/shares.php" + queryString, true);
        ajaxRequest.onload = function() {
          if (this.readyState === 4 && this.status === 200) {
            // do stuff
            var resp = JSON.parse(this.responseText);
            console.log(resp);
            for (var i = 0; i < resp.data.length; i++) {
              if (i === resp.data.length -1) {
                optiondata += "'"+resp.data[i].name+"'"; 
              }
              else {
                optiondata += "'"+resp.data[i].name+"',";
              }
            }
            console.log("onload:", optiondata); 
            resolve(optiondata); 
          } else {
            reject(this.status)
          }    
        };  
        ajaxRequest.send(null);
      });
    };

    request(queryString).then(function success(data) {
      console.log("returned data:", data)
    }, function error(err) {
      console.log(err)
    });

    var queryString = "?callFunction=get_all_data";
    var request = function(queryString) {
      return new Promise(function(resolve, reject) {
        var ajaxRequest = new XMLHttpRequest()
        , optiondata = "";
        ajaxRequest.open("GET", "https://gist.githubusercontent.com/guest271314/6a76aa9d2921350c9d53/raw/49fbc054731540fa68b565e398d3574fde7366e9/abc.txt", true);
        ajaxRequest.onload = function() {
          if (this.readyState === 4 && this.status === 200) {
            // do stuff
            optiondata = this.responseText;
            console.log("onload:", optiondata); 
            resolve(optiondata); 
          } else {
            reject(this.status)
          }    
        };  
        ajaxRequest.send(null);
      });
    };
    
    request(queryString).then(function success(data) {
      console.log("returned data:", data)
    }, function error(err) {
      console.log(err)
    });
guest271314
  • 1
  • 15
  • 104
  • 177