The function below has 2 alert boxes. When I run it, sometimes the outer alert box comes empty. Please explain in a human manner why .

function ItemCount()//returns the number of items in carousel
{


if (window.XMLHttpRequest) {
			var	req = new XMLHttpRequest();
		}
		else if (window.ActiveXObject) {
			var req = new ActiveXObject("Microsoft.XMLHTTP");
		}
		else
		{
		alert("upgrade browser");
		
		}
		
		
		req.open("POST", "/includes/_process/getPortfolioCount.php", true);
		req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		req.send(null);
		req.onreadystatechange = function() {
			if ((req.readyState == 4) && (req.status == 200)) {
					
		
				if (req.responseText.length) {
				
				
				document.getElementById('portfolioCount').value=req.responseText;
				
				alert(req.responseText);
				
				}
				
			}
		}
		
	alert("out:"+document.getElementById('portfolioCount').value);
		
		
	
		
	return document.getElementById('portfolioCount').value;
		
}//function

Ajax stands for asynchronous javascript and xml. Note that you set the onreadystatechange handler to that anonymous function, but you dont have any guarantee that that function will be executed immediately.. i.e. the request will go out, then the rest of the code in the function will execute, then at some undetermined point in the future, the code in the onreadystate handler will be executed, by then, the function that set the handler may have long since returned. If you really want synchronous ( in other words, the running of the function wont continue until the request is done ), change:

req.open("POST", "/includes/_process/getPortfolioCount.php", true);

to:

req.open("POST", "/includes/_process/getPortfolioCount.php", false);

But I've heard of support issues with this, so, if you can restructure slightly i.e. put the tail end of the function ( the part dependant on the state changing ) into the handler function, then do that instead.

Also, based on what I've just mentioned, it would be wise to call req.send(null); AFTER setting the readystatechange handler, since theres a non-zero chance that the request will be satisifed before the handler is actually assigned.

Thanks a lot for the detailed reply. It makes sense to do what you just said. My question is, that everyone promotes asynchronous calls but I have a real world example in which I have to do a synchronous call.

How does one structure a function so that you do not run into the dilemma that i am running into ?

There's at least two ways, one is to put all the code that is supposed to be executed after the response has been obtained into the end of the onreadystatechange handler function; the second way ( essentially the same ) is to split the requesting function into two functions, one that does the stuff that should occur before the readystate changes then issues the request then returns immediately, and one that does the stuff that occurs after the response is recieved, and call the second function from the readystatechange handler function.

The claimed issues with regard to bad support for syncronous requests are with relation to the onreadystatechange function not being called in versions of firefox ( i've never personally verified this ); if you're using a synchronous request though, you shouldn't need to worry about this issue anyway : the call to request.send won't return until the readystate has changed to the response recieved state, so you should be able to just write:

req.open("POST", "/includes/_process/getPortfolioCount.php", false);
req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
req.send(null);
if ( req.status == 200) {
  document.getElementById('portfolioCount').value=req.responseText;
  alert(req.responseText);
  //...etc...
} else {
  //error occured
}

( notice that a readystate change handler never need be assigned )

The only issue with synchronous otherwise, is that the javascript application will hang ( not continue to execute anything ) until a response is recieved.

This article has been dead for over six months. Start a new discussion instead.