...

View Full Version : My ajax script returns my response before it is completed



ghostz00
08-22-2007, 03:58 PM
Here is my script.


AJAX = {
xmlHttp:'',

init : function(methodType, url){

AJAX.xmlHttp=AJAX.getXmlHttpObject();

if (AJAX.xmlHttp==null){
alert ("Your browser does not support AJAX!");
return;
}

AJAX.xmlHttp.onreadystatechange=AJAX.stateChanged;
AJAX.xmlHttp.open(methodType,url,true);
AJAX.xmlHttp.send(null);

},

stateChanged : function(){
if (AJAX.xmlHttp.readyState==4){
return AJAX.xmlHttp.responseText;
}
},

getXmlHttpObject : function(){

AJAX.xmlHttp=null;

try {
// Firefox, Opera 8.0+, Safari
AJAX.xmlHttp=new XMLHttpRequest();
}
catch (e){

// Internet Explorer
try{
AJAX.xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e){
AJAX.xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}

}
return AJAX.xmlHttp;
}
}

I call it using something like this.


var response=AJAX.init("GET","./test.php");

But since the init function doesn't return anything response is undefined. How do I get my response from stateChanged function.

thanks,

ghostz00
08-22-2007, 04:12 PM
Ok so I found one way of handling this.

Turning off async and making the script wait for a response.

e.g.

Changing:



AJAX.xmlHttp.open(methodType,url,true);


To:



AJAX.xmlHttp.open(methodType,url,false);


But I've read that this is bad. Any explanations of why it is bad?

ghostz00
08-22-2007, 07:10 PM
The time it takes to execute the response goes up by more than 3x on my development server when using synchronous mode. With async on it takes anywhere from 4ms to 6ms according to firefox(firebug). And with the script waiting to sync it takes anywhere from 18ms to 21ms. Doesn't seem that bad, but if this was a production server under heavy load it, those numbers would probably get a lot worse.

So as for my solution I think I'll just go with async and just add an extra parameter to my init function. So along with the method and url I'm also going to be passing the object that I want to update with my responseText.



AJAX = {
xmlHttp:'',
divId:'',

init : function(methodType, url, divId){
AJAX.divId=divId;

AJAX.xmlHttp=AJAX.getXmlHttpObject();

if (AJAX.xmlHttp==null){
alert ("Your browser does not support AJAX!");
return;
}

AJAX.xmlHttp.onreadystatechange=AJAX.stateChanged;
AJAX.xmlHttp.open(methodType,url,true);
AJAX.xmlHttp.send(null);

},

stateChanged : function(){
if (AJAX.xmlHttp.readyState==4){
AJAX.divId.innerHTML=AJAX.xmlHttp.responseText;
}
},

getXmlHttpObject : function(){

AJAX.xmlHttp=null;

try {
// Firefox, Opera 8.0+, Safari
AJAX.xmlHttp=new XMLHttpRequest();
}
catch (e){

// Internet Explorer
try{
AJAX.xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e){
AJAX.xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}

}
return AJAX.xmlHttp;
}
}


And Make the call like:



var response=AJAX.init("GET","./test.php",document.getElementById("ajax"));


Please critique my code, I have no idea what I'm doing :)

rwedge
08-24-2007, 05:21 AM
Native use of XMLHttpRequest is supported by IE7.

Checking the status for 200 to handle any error may help if it takes awhile to receive the response

ghostz00
08-24-2007, 05:39 AM
Thanks for the reply

Shouldn't I leave that code to support IE 6? Also I'm not quite sure how to add a status check? I'm assuming that I'm doing the check before it gets to readyState 4.



if (AJAX.xmlHttp.readyState<4){

if (AJAX.xmlHttp.status="404"){
AJAX.xmlHttp.abort();
}
}


Is that what your talking about? If not could you give me an example? The more I think about it. The more it make sense to do something like that.

rwedge
08-24-2007, 08:17 AM
Leave the code in code to support the eariler versions of IE.

To handle the status
if (AJAX.xmlHttp.readyState==4){
if (AJAX.xmlHttp.status == 200) {
AJAX.divId.innerHTML=AJAX.xmlHttp.responseText;
} else {
// do something
// AJAX.xmlHttp.status // 404, 500 etc
// AJAX.xmlHttp.statusText // Not Found, Internal Server Error etc
}

}

ghostz00
08-24-2007, 01:21 PM
Ok I get it...

thanks

glenngv
08-27-2007, 08:33 AM
AJAX wrapper functions should be generic and reusable. Putting specific requirements as below will render it useless to other functionalities that need AJAX.

stateChanged : function(){
if (AJAX.xmlHttp.readyState==4){
AJAX.divId.innerHTML=AJAX.xmlHttp.responseText;
}
},

You should add a callback function in the init function in order for the onreadystatechange handler to call it once the response is available.

AJAX = {
xmlHttp:'',

init : function(methodType, url, callback){

AJAX.xmlHttp=AJAX.getXmlHttpObject();

if (AJAX.xmlHttp==null){
alert ("Your browser does not support AJAX!");
return;
}


AJAX.xmlHttp.open(methodType,url,true);
AJAX.xmlHttp.onreadystatechange=function(){AJAX.stateChanged(callback)};
AJAX.xmlHttp.send(null);

},

stateChanged : function(callback){
if (AJAX.xmlHttp.readyState==4){
if (AJAX.xmlHttp.status == 200) {
if (callback) callback(AJAX.xmlHttp.responseText);
}
}
},
...
}

function myCallbackFunction(responseText){
alert(responseText);
//do what you want with the response
}

var response=AJAX.init("GET","./test.php", myCallbackFunction);

ghostz00
08-27-2007, 01:28 PM
Thanks for the reply,

That is a good idea. One question though. What's up with this line?



AJAX.xmlHttp.onreadystatechange=function(){AJAX.stateChanged(callback)};


why not just:?



AJAX.xmlHttp.onreadystatechange=AJAX.stateChanged(callback);

glenngv
08-27-2007, 08:35 PM
Doing what you suggested would immediately call the stateChanged handler and assign the return of that function to onreadystatechange. You don't want to do that. What you want to do is as assign onreadystatechange to a function pointer.

What I did was I assign the onreadystatechange to an anonymous function. You can also assign it to a named function just like what you did here.

AJAX.xmlHttp.onreadystatechange=AJAX.stateChanged;
Take note that you didn't put () to the stateChanged function. If you put (), it would be immediately executed and not assign it to a handler. If your function has parameters, normally you would use an anonymous function. Thus the solution:

AJAX.xmlHttp.onreadystatechange=function(){AJAX.stateChanged(callback)};

ghostz00
08-27-2007, 08:46 PM
I get it....absolutely brilliant thanks for your help. That actually answers another one of my problems..

thanks again...

vijay1985
08-28-2007, 12:08 PM
im checking the forum



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum