• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 588
  • Last Modified:

I don't get responseText with GET unless I make a synchronous Ajax-call.. Why is that?

I have this in a php-file..


<script type="text/javascript">

      function callAjax(method, url, params, async, getResponse)
      {
              var xmlHttp;
      
              try {    
                        // Firefox, Opera 8.0+, Safari
                        xmlHttp = new XMLHttpRequest();
                        xmlHttp.overrideMimeType('text/html');
              }
              catch (e) {    
                        // Internet Explorer  
                        var XMLHTTP_IDS = new Array(
                                'MSXML2.XMLHTTP.5.0',
                                'MSXML2.XMLHTTP.4.0',
                                'MSXML2.XMLHTTP.3.0',
                                'MSXML2.XMLHTTP',
                                'Microsoft.XMLHTTP'
                        );
                        var success = false;
                        for (var x=0; x < XMLHTTP_IDS.length && !success; x++) {
                                try {
                                          xmlHttp = new ActiveXObject(XMLHTTP_IDS[x]);
                                          success = true;
                                }
                                catch (e) {}
                        }  
      
                        if (!success || typeof(xmlHttp) == "undefined") {
                                alert("Your browser does not support AJAX!");        
                                return false;
                        }
              }      
      
              // Handle response and failures
              var response;
              xmlHttp.onreadystatechange = function() {      
                        if (xmlHttp.readyState == 4 || xmlHttp.readyState == "complete") {            
                              if(xmlHttp.status == 200) response = xmlHttp.responseText;
                              else {
                                    //Error response, ie. 404
                              }
                        }
                        else {
                              //waiting
                        }
              };
      
              //Fire ajax
              url = url + '?nocache=' + Math.random() + params;
              xmlHttp.open(method, url, async);
              xmlHttp.send(null);
      
              //Return results
              if(!async) return xmlHttp.responseText;
      
              if(getResponse == true) {
                        return response;
              }
      }
      
      
      function test() {
            string_to_search = callAjax(method="GET", url="data.php", params="", async=true, getResponse=true);
            alert(string_to_search);
      }

</script>


<head>
</head>
<body onload="javascript:test();">
</body>


And this in a separate php-file:


<?php
      echo "SUPERGNU";                              
?>


But I get "undefined" when I try to alert the responseText..
in alert(string_to_search);

Unless I set async=false; wich then forces a synchronous call to be made.
And this seems to work the same without a ready-made function like ajaxCall..

So something is wierd with asynchronous get.. Anyone know why it doesn't work?


0
walkman69
Asked:
walkman69
  • 11
  • 6
1 Solution
 
numberkruncherCommented:
Could I recommend using a library like jQuery or PrototypeJS which makes using AJAX so much less complicated. Not only do these libraries make it easy to perform AJAX operations, but they also deal with various browser discrepancies for you.

Example with jQuery:
$.ajax({
    url: 'data.php',
    success: function(data) {
        alert('Your data: ' + data);
    }
});

Open in new window

0
 
numberkruncherCommented:
Some definitions:

Asynchronous: Make the AJAX request in parallel to the function call in JavaScript. Think of it as starting a new thread. The function "callAjax" will continue to execute even though AJAX has not got back to you with the result yet...that could come later.

Synchronous: Makes "callAjax" wait until AJAX has come back with the result....slow and not recommended.

With Asynchronous you can add your "success" logic within a callback (like in my example above).
0
 
walkman69Author Commented:
I would rather learn how it works, but thanx anyway.
0
The 14th Annual Expert Award Winners

The results are in! Meet the top members of our 2017 Expert Awards. Congratulations to all who qualified!

 
walkman69Author Commented:
I thought that xmlHttp.onreadystatechange = function() was the callback-function.
0
 
numberkruncherCommented:
Put your alert statement into the callback function:
<script type="text/javascript">

      function callAjax(method, url, params, async, getResponse)
      {
              var xmlHttp;
       
              try {    
                        // Firefox, Opera 8.0+, Safari
                        xmlHttp = new XMLHttpRequest();
                        xmlHttp.overrideMimeType('text/html');
              }
              catch (e) {    
                        // Internet Explorer  
                        var XMLHTTP_IDS = new Array(
                                'MSXML2.XMLHTTP.5.0',
                                'MSXML2.XMLHTTP.4.0',
                                'MSXML2.XMLHTTP.3.0',
                                'MSXML2.XMLHTTP',
                                'Microsoft.XMLHTTP'
                        );
                        var success = false;
                        for (var x=0; x < XMLHTTP_IDS.length && !success; x++) {
                                try {
                                          xmlHttp = new ActiveXObject(XMLHTTP_IDS[x]);
                                          success = true;
                                }
                                catch (e) {}
                        }  
       
                        if (!success || typeof(xmlHttp) == "undefined") {
                                alert("Your browser does not support AJAX!");        
                                return false;
                        }
              }      
       
              // Handle response and failures
              var response;
              xmlHttp.onreadystatechange = function() {      
                        if (xmlHttp.readyState == 4 || xmlHttp.readyState == "complete") {            
                              if(xmlHttp.status == 200) {
									alert(xmlHttp.responseText);
								}
                              else {
                                    //Error response, ie. 404
                              }
                        }
                        else {
                              //waiting
                        }
              };
       
              //Fire ajax
              url = url + '?nocache=' + Math.random() + params;
              xmlHttp.open(method, url, async);
              xmlHttp.send(null);
       
              //Return results
              if(!async) return xmlHttp.responseText;
       
              if(getResponse == true) {
                        return response;
              }
      }
      
      
      function test() {
            callAjax(method="GET", url="data.php", params="", async=true, getResponse=true);
      }

</script>


<head>
</head>
<body onload="javascript:test();">
</body>


And this in a separate php-file:


<?php
      echo "SUPERGNU";                              
?>

Open in new window

0
 
walkman69Author Commented:
I mean, shouldn't this be called when the page is fully loaded?

if (xmlHttp.readyState == 4 || xmlHttp.readyState == "complete") { ....



The ugly thing is that when i add some alert("xmlHttp.responseText") inside the  
if (xmlHttp.readyState == 4 || xmlHttp.readyState == "complete")

And alert("not yet ready") inside the else statement (When the page still is not loaded.)
There is shown 3 "not yet ready", 1 "SUPERGNU", and 1 "not yet ready"

I've read that the callback function is called everytime the readyState changes..
So I take it it changes 3 times until readyState == 4 then shows the "SUPERGNU", and then it is called again when it is reset or something like that.

What i can't figure out is why it doesn't show "SUPERGNU" when I don't do the  
alert("not yet ready").

Perhaps it has something with the loading-time to do like you said.

I know I've tried to add a timer on 10/1000 seconds, but perhaps that's to little.



0
 
numberkruncherCommented:
If you want to wait until AJAX response is received you have to call it async = false. It then waits until the response is received.

Otherwise, your callback logic (and alert) should be within the callback function under status 200 (success).
0
 
walkman69Author Commented:
ok, that was interesting..
0
 
walkman69Author Commented:
I'll explore this for a couple of minutes and se what i get..
0
 
walkman69Author Commented:
This is seriously breathing down my neck..

Why does the alert() inside the callback work and the returned value still shows undefined in the other alert?? Am i declaring the return values wrong? Or can't it return?



<script type="text/javascript">

      function callAjax(method, url, params, async, getResponse)
      {
              var xmlHttp;
      
              try {    
                        // Firefox, Opera 8.0+, Safari
                        xmlHttp = new XMLHttpRequest();
                        xmlHttp.overrideMimeType('text/html');
              }
              catch (e) {    
                        // Internet Explorer  
                        var XMLHTTP_IDS = new Array(
                                'MSXML2.XMLHTTP.5.0',
                                'MSXML2.XMLHTTP.4.0',
                                'MSXML2.XMLHTTP.3.0',
                                'MSXML2.XMLHTTP',
                                'Microsoft.XMLHTTP'
                        );
                        var success = false;
                        for (var i=0; i < XMLHTTP_IDS.length && !success; i++) {
                                try {
                                          xmlHttp = new ActiveXObject(XMLHTTP_IDS[i]);
                                          success = true;
                                }
                                catch (e) {}
                        }  
      
                        if (!success || typeof(xmlHttp) == "undefined") {
                                alert("Your browser does not support AJAX!");        
                                return false;
                        }
              }      
      
              // Handle response and failures
              var response;
              xmlHttp.onreadystatechange = function() {      
                        if (xmlHttp.readyState == 4 || xmlHttp.readyState == "complete") {            
                              if(xmlHttp.status == 200) {response = xmlHttp.responseText;
                                    //alert(xmlHttp.responseText);
                                    //Return results       
                                    if(getResponse == true) {
                                        alert(xmlHttp.responseText);
                                          return xmlHttp.responseText;
                                    }

                              
                              }
                              else {
                                    //Error response, ie. 404
                              }
                        }
                        else {
                              //waiting
                        }
              };
      
              //Fire ajax
              url = url + '?nocache=' + Math.random() + params;
              xmlHttp.open(method, url, async);
              xmlHttp.send(null);
      
              //Return results       
              if(getResponse == true) {
                    if(!async) {
                        return xmlHttp.responseText;
                    }
              }
      }
      
      
      function test() {
            string_to_search = callAjax(method="GET", url="data.php", params="", async=true, getResponse=true);
            alert(string_to_search);
      }

</script>


<head>
</head>
<body onload="javascript:test();">
</body>
0
 
numberkruncherCommented:
The alert in "test" cannot work for asynchronous calls because the alert is shown before the AJAX request has got back to the web browser.

The alert in "test" can only work for synchronous calls.

The following webpage might help explain this:
http://yuiblog.com/blog/2006/04/04/synchronous-v-asynchronous/
0
 
walkman69Author Commented:
*feeling stupid*... of course that's why it doesn't work.

Thanks for your help numberkruncher.
0
 
walkman69Author Commented:
This means I have to send a pointer of some kind to get the return-values.

Perhaps I just need to send a namespace-variable to store the result, and then launch an init-function to handle this when the php-file has been fully loaded.
0
 
numberkruncherCommented:
I personally would just use a namespace variable, I usually make the following definition to clarify reading:
// Global namespace is window, but $global makes more sense.
var $global = window;

// Your variable:
$global.yourVariable = 42;

Open in new window

0
 
walkman69Author Commented:
ok, i just use a:

var g = {
     myVariable : ""
}

I heard somewhere that it was a better method than using window.
But then again I haven't been using namespaces for very long.

I just know for sure that window is better to use than declaring global variables directly
in the document.








0
 
walkman69Author Commented:
Anyway.. it ended up looking somewhat like this:
And it works like a charm..



<script type="text/javascript">

      var g = {
            ajaxResponseText : ""
      }
      
      function testInit() {
            alert(g.ajaxResponseText);
      }
      

      function callAjax(method, url, params, async, getResponse, namespace, initFunctions, elem)
      {
              var xmlHttp;
      
              try {    
                        // Firefox, Opera 8.0+, Safari
                        xmlHttp = new XMLHttpRequest();
                        xmlHttp.overrideMimeType('text/html');
              }
              catch (e) {    
                        // Internet Explorer  
                        var XMLHTTP_IDS = new Array(
                                'MSXML2.XMLHTTP.5.0',
                                'MSXML2.XMLHTTP.4.0',
                                'MSXML2.XMLHTTP.3.0',
                                'MSXML2.XMLHTTP',
                                'Microsoft.XMLHTTP'
                        );
                        var success = false;
                        for (var i=0; i < XMLHTTP_IDS.length && !success; i++) {
                                try {
                                          xmlHttp = new ActiveXObject(XMLHTTP_IDS[i]);
                                          success = true;
                                }
                                catch (e) {}
                        }  
      
                        if (!success || typeof(xmlHttp) == "undefined") {
                                alert("Your browser does not support AJAX!");        
                                return false;
                        }
              }      
      
              // Handle response and failures
              var response;
              xmlHttp.onreadystatechange = function() {      
                        if (xmlHttp.readyState == 4 || xmlHttp.readyState == "complete") {            
                              if(xmlHttp.status == 200) {
                                    
                                    if (elem) { document.getElementById(elem).innerHTML=xmlhttp.responseText; }
                                          
                                          // Return results thru namespace-variable if this is requested
                                          if ((getResponse == true) && (namespace)) {
                                                // Set namespace variable
                                                namespace.ajaxResponseText = xmlHttp.responseText;
                                          }      
                                                                        
                                          function initFunctionsLoader() {      
                                                if (initFunctions.length > 0) {
                                                      for(x = 0; x < initFunctions.length; x++) {
                                                            initFunctions[x]();
                                                            
                                                      }
                                                }
                                          }
                                    
                                          if (elem) {
                                                var _timer = setInterval(function() {
                                                      // Check if all DOM-elements has been loaded into elem
                                                      if (/loaded|complete/.test(document.readyState)) {
                                                            // If so, remove the timer
                                                            clearInterval(_timer);
                                                            delete _timer;
                                                            // And start up any given function
                                                            initFunctionsLoader();
                                                      }
                                                }, 10);                  
                                          } else {
                                                // If there aint any DOM objects to load then run initFunctions() immediatly.
                                                initFunctionsLoader();                                    
                                          }                                    
                              }
                              else {
                                    //Error response, ie. 404
                              }
                        }
                        else {
                              //waiting
                        }
              };
      
              //Fire ajax
              url = url + '?nocache=' + Math.random() + params;
              xmlHttp.open(method, url, async);
              xmlHttp.send(null);
      
              //Return results       
              if(getResponse == true) {
                    if(!async) {
                        return xmlHttp.responseText;
                    }
              }
      }
      
      
      function test() {
            init_functions = [testInit];
            callAjax(method="GET", url="data.php", params="", async=true, getResponse=true, namespace = g, init_functions, elem = "");
      }


      
      
      


</script>


<head>
</head>
<body onload="javascript:test();">
</body>

0
 
walkman69Author Commented:
if an elementId elem is sent as argument then any response from the php-file will be outputted into this.
But i'll probably gonna change it so it handles an object directly instead of having to search its ID.

It's not near complete yet..

But as you can see some init-functions can also be called, and when loading data into elements, they are not called until every DOM element is created inside the elementID-element. This due to the fact that certain commands aint applicable on the DOM-elements unless they actually exists.. Wich is quite logical ^^
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

The 14th Annual Expert Award Winners

The results are in! Meet the top members of our 2017 Expert Awards. Congratulations to all who qualified!

  • 11
  • 6
Tackle projects and never again get stuck behind a technical roadblock.
Join Now