Java Script Function not returning value from Ajax request

341 Views Asked by At

I have following AJax request function which is working fine. upon successful it returns 1 else 2.

Now i would like to perform some action outside of this function based on this return value, as below, but its not working .. it always returns "undefined"...

I expect the return_code should return either 1 or 2 based on following code

<script>

var return_code=add_to_cart_ajax(200);
alert(return_code);
</script>
returns "undefined"

AJAX Request :

<script>
//Ajax to send request to add 
function add_to_cart_ajax(id)
{
    if (window.XMLHttpRequest)
      {// code for IE7+, Firefox, Chrome, Opera, Safari
      xmlhttp=new XMLHttpRequest();
      }
    else
      {// code for IE6, IE5
      xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
      }
        xmlhttp.onreadystatechange=function()
          {
          if (xmlhttp.readyState==4 && xmlhttp.status==200)
            {
alert(xmlhttp.responseText); // returns 1 
                if (xmlhttp.responseText==1)
                {
                    return 1;
                }
                else
                {
                    return 2;
                }
            }
          }
    xmlhttp.open("GET","add.php?id="+id,true);
    xmlhttp.send();
}//end of the function..
</script>
3

There are 3 best solutions below

9
ivarni On BEST ANSWER

Since an AJAX call is asynchronous one common way of dealing with it is to use a callback-function that gets called once the request is processed.

Something like

<script>
  add_to_cart_ajax(200, function(return_code) {
     alert(return_code);
  });
</script>


<script>
  //Ajax to send request to add 
  function add_to_cart_ajax(id, callback) {

    ...

    alert(xmlhttp.responseText); // returns 1 
    if (xmlhttp.responseText==1) {
      callback(1);
    } else {
      callback(2);
    }

    ...        

  }//end of the function..
</script>

EDIT: If you need to hang on to the return_code, you'd do

<script>
  var return_code;
  add_to_cart_ajax(200, function(result) {
     return_code = result;
  });
</script>

But it's important to understand that since the AJAX request is asynchronous, your return_code variable will not have a value assigned to it untill the AJAX request is fulfilled and you can't use it for anything untill that has happened, so any code that needs to do something with return_code should be included in or called from the callback. This is one of the things that is going to be a bit hard to grasp at first if you're coming from a background where all code is being run top-to-down. That's simply not the case once you start working with asynchronous stuff.

2
ilpaijin On

Seeing that an ajax call is async, you can't expect to have the result in your alert(return_code); because effectively at that time the ajax call has not get the response yet.

Could be useful to give a look at how libraries as jQuery or Zepto have done as well as implementing something following "promise" logic, just to avoid the callback hell.

6
Manuel Richarz On

ok i will try to make an example:

if you order a package on amazon and you want to unpack this in the next step

orderPackage();
unpackPackage(); // undefined / exception, because you have to wait for the package to be arrived

try not to return a value with the "onreadystatechange". you can call another function from inside this method or you can set global variables. as example:

Just to explain how ajax works (DO NOT USE THIS PEACE OF CODE, SCROLL DOWN FOR BETTER SOLUTION!):

ajaxReturn = null;

function add_to_cart_ajax(id) {
    if (window.XMLHttpRequest)
      {// code for IE7+, Firefox, Chrome, Opera, Safari
      xmlhttp=new XMLHttpRequest();
      }
    else
      {// code for IE6, IE5
      xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
      }
        xmlhttp.onreadystatechange=function()
          {
          if (xmlhttp.readyState==4 && xmlhttp.status==200)
            {
                ajaxReturn = xmlhttp.responseText;
            }
          }
    xmlhttp.open("GET","add.php?id="+id,true);
    xmlhttp.send();

    while(ajaxReturn == null) {
    //waiting for response
    //will break if the request is finished
    }

    alert(ajaxReturn);

}//end of the function..

Please not use this in productive because the while will cause the browser to stop i think. but this should explain the behaviour to you.

Right Solutions

// This will send an ajax-request and execute the fCallback if finished
// @param sUrl - Url to send the request to
// @param fCallbackSuccess - method that will be executed on successfull request
// @param fCallbackFailed - method that will be executed on failed request
// @param bAsync - will make the request async or sync
function ajax(sUrl, fCallbackSuccess, fCallbackFailed, bAsync) {
        if (window.XMLHttpRequest) {
          oXmlHttp=new XMLHttpRequest();
        } else {
          oXmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
        }
        oXmlHttp.onreadystatechange=function() {
           if (oXmlHttp.readyState==4 && oXmlHttp.status==200) {
                fCallbackSuccess.apply(oXmlHttp);
                return;
           }
           fCallbackFailed.apply(oXmlHttp);
        }
        oXmlHttp.open("GET", sUrl, bAsync);
        oXmlHttp.send();
}

//usage example:

var fSuccess = function(oXmlHttp) {
   //do something with oXmlHttp
   alert(oXmlHttp.responseText);
}

var fFailed= function(oXmlHttp) {
   //do something with oXmlHttp
   alert('Request failed!');
}

ajax("add.php?id="+id, fSuccess, fFailed, true);

have a nice day