When I call for getCurrentConditions it tries to return data before requestData has completed and therefore doesn't find data.currently. I am definately getting data returned from the URL, I have tried adding a timeout loop to wait for the XHR to load, but that just broke the script all together. I am kind of confused why the second function is not waiting for this.requestData(latitude, longitude); to finish before continuing.
this.requestData = function(latitude, longitude) {
request_url = self.API_ENDPOINT + api_key + '/' + latitude + ',' + longitude + '?units=auto';
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if(xhr.readyState==4 && xhr.status==200) {
content = xhr.responseText;
if(content != '' && (content)) {
return JSON.parse(content);
} else {
return false;
}
}
}
xhr.open('GET', 'proxy.php?url='+request_url, true);
xhr.send(null);
}
/**
* Will return the current conditions
*
* @param float $latitude
* @param float $longitude
* @return \ForecastIOConditions|boolean
*/
this.getCurrentConditions = function(latitude, longitude) {
data = this.requestData(latitude, longitude);
if(data !== false) {
return new ForecastIOConditions(data.currently);
} else {
return false;
}
}
var forecast = new ForecastIO(api_key);
var condition = forecast.getCurrentConditions(latitude, longitude);
When I call for getCurrentConditions it tries to return data before requestData has completed and therefore doesn't find data.currently. I am definately getting data returned from the URL, I have tried adding a timeout loop to wait for the XHR to load, but that just broke the script all together. I am kind of confused why the second function is not waiting for this.requestData(latitude, longitude); to finish before continuing.
this.requestData = function(latitude, longitude) {
request_url = self.API_ENDPOINT + api_key + '/' + latitude + ',' + longitude + '?units=auto';
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if(xhr.readyState==4 && xhr.status==200) {
content = xhr.responseText;
if(content != '' && (content)) {
return JSON.parse(content);
} else {
return false;
}
}
}
xhr.open('GET', 'proxy.php?url='+request_url, true);
xhr.send(null);
}
/**
* Will return the current conditions
*
* @param float $latitude
* @param float $longitude
* @return \ForecastIOConditions|boolean
*/
this.getCurrentConditions = function(latitude, longitude) {
data = this.requestData(latitude, longitude);
if(data !== false) {
return new ForecastIOConditions(data.currently);
} else {
return false;
}
}
var forecast = new ForecastIO(api_key);
var condition = forecast.getCurrentConditions(latitude, longitude);
Share
Improve this question
asked Apr 18, 2013 at 10:36
Ian TearleIan Tearle
3451 gold badge5 silver badges14 bronze badges
1
- exact duplicate of How to return the response from an AJAX call? – Bergi Commented Apr 18, 2013 at 10:41
4 Answers
Reset to default 13Because ajax is asynchronous, means once the request is sent it will continue executing without waiting for the response.
One easy solution is to turn off the asynchronous nature by passing the 3rd parameter to the .open() method as false, but it has drawbacks like the browser thread will be blocked till the request is completed means UI will remain unresponsive till the request is completed.
xhr.open('GET', 'proxy.php?url='+request_url, false);
The correct solution will be is to use a callback method
this.requestData = function(latitude, longitude, callback) {
request_url = self.API_ENDPOINT + api_key + '/' + latitude + ',' + longitude + '?units=auto';
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if(xhr.readyState==4 && xhr.status==200) {
content = xhr.responseText;
if(content != '' && (content)) {
callback(JSON.parse(content));
} else {
callback(false);
}
}
}
xhr.open('GET', 'proxy.php?url='+request_url, true);
xhr.send(null);
}
/**
* Will return the current conditions
*
* @param float $latitude
* @param float $longitude
* @return \ForecastIOConditions|boolean
*/
this.getCurrentConditions = function(latitude, longitude, callback) {
this.requestData(latitude, longitude, function(data) {
if(data !== false) {
callback(ForecastIOConditions(data.currently));
} else {
callback(false);
}
});
}
var forecast = new ForecastIO(api_key);
forecast.getCurrentConditions(latitude, longitude, function(condition){
if(condition !== false) {
} else {
}
});
instead of
xhr.open('GET', 'proxy.php?url='+request_url, true);
use
xhr.open('GET', 'proxy.php?url='+request_url, false);
About method:
open(method,url,async)
Specifies the type of request, the URL, and if the request should be handled asynchronously or not.
method:
the type of request: GET or POST
url:
the location of the file on the server
async:
true (asynchronous) or false (synchronous)
Source: w3schools
put false
instead of true
here
// `false` makes the request synchronous
xhr.open('GET', 'proxy.php?url='+request_url, false);
this make call Synchronous instead of aSynchronous. so when call become Synchronous its wait for ajax call to complete and than execute the function you want.
Mozila link for XMLHttpRequest: Synchronous and asynchronous requests
It's asynch call. Try to use callback function. Code below is a sample. Not tested!
this.requestData = function(latitude, longitude, callback) {
request_url = self.API_ENDPOINT + api_key + '/' + latitude + ',' + longitude + '?units=auto';
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if(xhr.readyState==4 && xhr.status==200) {
content = xhr.responseText;
if(content != '' && (content)) {
callback(JSON.parse(content));
} else {
return false;
}
}
}
xhr.open('GET', 'proxy.php?url='+request_url, true);
xhr.send(null);
}
/**
* Will return the current conditions
*
* @param float $latitude
* @param float $longitude
* @return \ForecastIOConditions|boolean
*/
this.getCurrentConditions = function(latitude, longitude) {
this.requestData(latitude, longitude, callback);
}
this.callback = function(data) {
if(data !== false) {
return new ForecastIOConditions(data.currently);
} else {
return false;
}
};