If I take the alert call out of the following script firebug says that results is undefined?`
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" ".dtd">
<html>
<head>
<title>Inventory Management</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Untitled Document</title>
<script src="json.js" type="text/javascript"></script>
<script src="prototype.js" type="text/javascript"></script>
</head>
<body>
<div id="content">
<div id="header">
</div>
<script type="text/javascript">
var xhr;
var results=getPlants(xhr,results);
var plants=[];
function getPlants(xhr,results){
try {
xhr=new XMLHttpRequest();
}catch(microsoft){
try{
xhr=new ActiveXObject("Msxml2.XMLHTTP");
}catch(othermicrosoft){
try{
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}catch(failed){
xhr=false;
alert("ajax not supported");
}
}
}
xhr.onreadystatechange= function () {
if(xhr.readyState==4 && xhr.status==200) {
results = xhr.responseText;
}
}
xhr.open("GET","db_interactions.php",true);
xhr.send(null);
alert("sent");
return results;
}
plants.inv=[];
plants.split = results.split("~");
for (var x=0;x<=plants.split.length-2;x++){
plants.inv[x]=plants.split[x].evalJSON();
}
document.write(plants.inv[1].scientific_name);
</script>
</div>
</body>
</html>
If I take the alert call out of the following script firebug says that results is undefined?`
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3/TR/html4/strict.dtd">
<html>
<head>
<title>Inventory Management</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Untitled Document</title>
<script src="json.js" type="text/javascript"></script>
<script src="prototype.js" type="text/javascript"></script>
</head>
<body>
<div id="content">
<div id="header">
</div>
<script type="text/javascript">
var xhr;
var results=getPlants(xhr,results);
var plants=[];
function getPlants(xhr,results){
try {
xhr=new XMLHttpRequest();
}catch(microsoft){
try{
xhr=new ActiveXObject("Msxml2.XMLHTTP");
}catch(othermicrosoft){
try{
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}catch(failed){
xhr=false;
alert("ajax not supported");
}
}
}
xhr.onreadystatechange= function () {
if(xhr.readyState==4 && xhr.status==200) {
results = xhr.responseText;
}
}
xhr.open("GET","db_interactions.php",true);
xhr.send(null);
alert("sent");
return results;
}
plants.inv=[];
plants.split = results.split("~");
for (var x=0;x<=plants.split.length-2;x++){
plants.inv[x]=plants.split[x].evalJSON();
}
document.write(plants.inv[1].scientific_name);
</script>
</div>
</body>
</html>
Share
Improve this question
edited Jan 26, 2010 at 21:31
Josh Mein
28.7k15 gold badges78 silver badges88 bronze badges
asked Jan 26, 2010 at 21:12
Daquan HallDaquan Hall
372 bronze badges
4
- 1 I think you need to reformat, for easier reading by SO users. – sberry Commented Jan 26, 2010 at 21:14
- 1 A few observations: don't use exceptions for flow control - they're very slow and makes code hard to read. Also, don't declare js functions in the middle of your markup; put them in the head or after the body. And reformat your code so we can read it, please. – 3Dave Commented Jan 26, 2010 at 21:16
- And you may want to use one of the frameworks to take care of the browser-specific AJAX stuff. I thinkg you could reduce your script's volume by 50% by using JQuery or Prototype. (It's entirely optional and not really necessary. It just makes life easier.) – Pekka Commented Jan 26, 2010 at 21:18
- This has been asked before. It's a mon problem. Search before you ask, please. stackoverflow./questions/1267454/… – Josh Stodola Commented Jan 26, 2010 at 21:37
5 Answers
Reset to default 8The reason it's not working is because the XmlHttpRequest
is asynchronous. What this means is that you cannot do return results;
Here's a timeline, with your alert box:
- Create XmlHttpRequest
- Send it
- Alert box pops up and sits there for a while
- XmlHttpRequest result es back and sets the
results
variable in youronreadystatechange
function - You click OK on the alert box
- the function returns (the
return results
line) - Other code runs and does things with the
results
variable.
Here's the timeline without the alert box:
- Create XmlHttpRequest
- Send it
- the function returns (the
return results
line) - Other code runs and does things with the
results
variable. This fails because it hasn't been set yet - XmlHttpRequest result es back and sets the
results
variable in youronreadystatechange
function
Instead you have to put the plants code (splitting, etc) in the onreadystatechange
callback, or put it in it's own function, and call that function from the onreadystatechange
You should modify the plants
variable in the callback function assigned to the onreadystatechange property.
xhr.onreadystatechange = function(){
if(xhr.readyState==4 && xhr.status==200) {
results = xhr.responseText;
// Populate the "plants" variable here, then call a function
// that does something with the plants variable.
}
}
For more information: https://developer.mozilla/en/AJAX/Getting_Started
When you call
xhr.open("GET","db_interactions.php",true);
you are telling the XMLHttpRequest to operate asynchronously. You are telling it to go off and do its work, calling the callback function at some unspecified time in the future, when the request has been fully processed. Change that true
to false
, and it will work as you expect. On the other hand, that function might hang indefinitely in the event of a network slowdown, etc., so caveat programmor.
The callback function that sets the 'results' variable is asynchronous -- meaning that it will likely get set after the return statement, unless there's something to delay the return statement (e.g. an alert() call).
XMLHttpRequest.send() is asynchronous. Without the alert the function runs faster than the ajax call and results is never initialized. You can fix this by changing the true
in your open call to false
to make it synchronous or set your global variable in your inline function