Reputation: 7468
How could I correct the code below so that it does not return the undefined
value for the getPreciseLocation
function?
In summary, there should be an AJAX call to get the current weather when the user clicks the #precise-location-prompt
and shares the location with the browser. However at the moment there is an undefined
value error straight after the user clicks on the #precise-location-prompt
.
// Get weather data for the current location
function getCurrentWeather(coordinates) {
return $.ajax('http://www.example.com/lat=' + coordinates[0] + '&lon=' + coordinates[1]);
}
// Show weather in DOM
function showCurrentWeather(data) {
var currentTemperature = data.temperature;
$('#current-temperature').text(currentTemperature);
}
// Get precise location based via the Geolocation API
function getPreciseLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(displayPosition, displayError);
} else {
console.log("Geolocation is not supported by this browser");
}
}
// Success function for the Geolocation API
function displayPosition(position) {
return [position.coords.latitude, position.coords.longitude];
}
// Error function for the Geolocation API
function displayError(error) {
console.log('Precise location is not available at the moment.');
}
// Promises chain with the AJAX requests
function getWeatherWrapper() {
return getPreciseLocation().then(function(locationData) {
return getCurrentWeather(locationData);
}).then(function(weatherData) {
return showCurrentWeather(weatherData);
});
}
// User's interaction with the website
$('#precise-location-prompt').on('click', getWeatherWrapper);
Upvotes: 3
Views: 6859
Reputation: 63579
This demo uses the JSfiddle AJAX methods (which, strangely, uses Mootools) to mock the request but you can substitute in the $.ajax
method. I also substituted the rest of the jQuery for vanilla JS event listeners and selectors for this test, but you can add them back in for your code very easily.
Return a new promise which resolves in the success
callback.
function getCurrentWeather(coordinates) {
return new Promise(function (resolve, reject) {
new Request.JSON({
url: '/echo/json/',
data: {
json: JSON.encode({ temperature: 'Too hot!' }),
delay: 1
},
onSuccess: function (response) {
resolve(response);
}
}).send();
});
}
function showCurrentWeather(data) {
var temp = document.getElementById('current-temperature');
temp.textContent = data.temperature;
}
Return a promise that resolves when your original displayPosition
was called. I added back that function back into getPreciseLocation
because it was easier to get it working. You can also add back in your checks for geolocation here, and a reject
as you see fit.
function getPreciseLocation() {
return new Promise(function (resolve, reject) {
navigator.geolocation.getCurrentPosition(function (position) {
resolve([position.coords.latitude, position.coords.longitude]);
});
});
}
Here we just reduce the code footprint to call the relevant functions with the appropriate data.
function getWeatherWrapper() {
getPreciseLocation()
.then(getCurrentWeather)
.then(showCurrentWeather);
}
var prompt = document.getElementById('precise-location-prompt');
prompt.addEventListener('click', getWeatherWrapper);
Upvotes: 13