Solved

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

Posted on 2010-11-09
17
564 Views
Last Modified: 2012-05-10
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
Comment
Question by:walkman69
  • 11
  • 6
17 Comments
 
LVL 13

Expert Comment

by:numberkruncher
ID: 34091674
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
 
LVL 13

Expert Comment

by:numberkruncher
ID: 34091689
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
 
LVL 2

Author Comment

by:walkman69
ID: 34091693
I would rather learn how it works, but thanx anyway.
0
 
LVL 2

Author Comment

by:walkman69
ID: 34091705
I thought that xmlHttp.onreadystatechange = function() was the callback-function.
0
 
LVL 13

Expert Comment

by:numberkruncher
ID: 34091748
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
 
LVL 2

Author Comment

by:walkman69
ID: 34091755
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
 
LVL 13

Expert Comment

by:numberkruncher
ID: 34091771
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
 
LVL 2

Author Comment

by:walkman69
ID: 34091799
ok, that was interesting..
0
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
LVL 2

Author Comment

by:walkman69
ID: 34091811
I'll explore this for a couple of minutes and se what i get..
0
 
LVL 2

Author Comment

by:walkman69
ID: 34091924
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
 
LVL 13

Accepted Solution

by:
numberkruncher earned 500 total points
ID: 34091947
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
 
LVL 2

Author Closing Comment

by:walkman69
ID: 34092012
*feeling stupid*... of course that's why it doesn't work.

Thanks for your help numberkruncher.
0
 
LVL 2

Author Comment

by:walkman69
ID: 34092035
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
 
LVL 13

Expert Comment

by:numberkruncher
ID: 34092076
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
 
LVL 2

Author Comment

by:walkman69
ID: 34094094
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
 
LVL 2

Author Comment

by:walkman69
ID: 34094118
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
 
LVL 2

Author Comment

by:walkman69
ID: 34094301
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

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

I found this questions asking how to do this in many different forums, so I will describe here how to implement a solution using PHP and AJAX. The logical flow for the problem should be: Write an event handler for the first drop down box to get …
International Data Corporation (IDC) prognosticates that before the current the year gets over disbursing on IT framework products to be sent in cloud environs will be $37.1B.
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now