-1

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>
logan
  • 7,946
  • 36
  • 114
  • 185

3 Answers3

2

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.

ivarni
  • 17,658
  • 17
  • 76
  • 92
  • what does callback(1) mean ? there is no function defined for callback – logan Mar 29 '14 at 09:31
  • `function add_to_cart_ajax(id, callback)` dictates that the `add_to_cart_ajax` function takes an argument that is the `callback`. It then calls that function once the request is completed. If you look at the top code-block you'll see that this is passed in after the `id` of 200. – ivarni Mar 29 '14 at 09:36
  • 1
    You can read more about callbacks here: http://recurial.com/programming/understanding-callback-functions-in-javascript/ – ivarni Mar 29 '14 at 09:37
  • Once you have a good grip on callbacks, I also suggest looking into `promises`, which often tends to be a cleaner way of handling asynchronous code. – ivarni Mar 29 '14 at 09:37
  • can i do like this ? i need to store the return code. `var return_code= add_to_cart_ajax(200, function(return_code) { return 1; });` – logan Mar 29 '14 at 09:41
  • I've made an edit to my answer. – ivarni Mar 29 '14 at 09:46
  • okay. then my code wont work ? – logan Mar 29 '14 at 10:02
  • No, the way you posted it in the original question, it will never work because it does not handle the asynchronous nature of an AJAX request. I strongly suggest reading up on asynchronous programming because it is a concept that you need to understand if you're going to do any kind of browser-server communication with Javascript. – ivarni Mar 29 '14 at 10:04
  • Also,if i call `add_to_cart_ajax(id, callback)` multiple times in another loop its not working... works for only last loop iteration – logan Mar 29 '14 at 10:07
0

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.

ilpaijin
  • 3,645
  • 2
  • 23
  • 26
0

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

Manuel Richarz
  • 1,916
  • 13
  • 27
  • downvote? greate i can live with that... but please explain also for others. use the commentbox for that. thanks – Manuel Richarz Mar 29 '14 at 08:51
  • if you read my post carefully..... you will see. – Manuel Richarz Mar 29 '14 at 08:58
  • the problem in the main question is not the return of 1 or 2. the problem is the understanding of async ajax. and this is what i want to explain in my post. yes of course callbacks are the better solution. but in the first step he has to understand how it works. – Manuel Richarz Mar 29 '14 at 09:01
  • ok let me do some changes. – Manuel Richarz Mar 29 '14 at 09:06
  • I am not seeing any down vote ! what do you mean by oXmlHttp ? and whats the difference between oXmlHttp and xmlHttp ? – logan Mar 29 '14 at 09:37
  • no difference between oXmlHttp and xmlHttp! it is just a different naming convention. i name every variable by its type: f = function, b = boolean, o = object, i = integer and so on. so anybody know what's inside this variable. – Manuel Richarz Mar 30 '14 at 13:44