I’m trying to write a script to retrieve a WOEID and interface with the Yahoo Weather API. I’m constructing a URL based on latitude and longitude values from stuff in a database I’m using, and can do this perfectly fine.
However, when it comes to storing that URL as a string that I can use in other functions, I’m having trouble. After some initial reading it seems to be a problem to do with onreadystatechange and scope, but I can’t seem to get my head around it to be able to store my variable.
Here is my code so far:
//<![CDATA[
var latitude = "";
var longitude = "";
var yahooAppID = "";
var yql = "";
//example yahoo request
//http://where.yahooapis.com/geocode?q=38.898717,+-77.035974&gflags=R&appid=SKUTk24k
function getLatLng() {
var routeID = 5;
var get = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
get.open('POST','process.php', true)
get.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
get.send('command=fetch&rid='+routeID);
get.onreadystatechange = function(){
if(get.readyState==4 && get.status == 200) {
os = eval('(' + get.responseText + ')');
latitude = os.start.lat;
longitude = os.start.lng;
//var yql = 'select * from flickr.places where lat='+latitude+' and lon='+longitude;
yql = "select * from flickr.places where lat=" +latitude+ " and lon="+longitude;
}
document.write(yql);
}
document.write(yql);
}
function test() {
getLatLng();
}
//]]>
The first document.write(yql); seems to produce the correct string, but the second does not, so I know that the value has not stuck.
Thanks in advance if anyone can help.
You’re not looking at a scoping issue — rather, a timing issue. AJAX requests (at least the way you’ve configured it) happen asynchronously, so the rest of your script will execute while the AJAX request is loading. So
yqlwon’t be updated until the very end.Also, warning: by the time the request completes, you can no longer use
document.write. Usealert()or DOM manipulation.Life cycle looks like this:
onreadystatechangeyqlwhen the ready state is “done.”yql.So, just call your processing function from inside the if:
jsFiddle