Reputation: 477
I'm using a simple script to geocode addresses.
var geocoder;
var departure;
var arrival;
function initialize() {
geocoder = new google.maps.Geocoder();
}
google.maps.event.addDomListener(window, 'load', initialize);
function geocode(options) {
var address = options.address.val() || null;
var result = {};
if (address) {
geocoder.geocode( { 'address': address }, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
result.lat = results[0].geometry.location.lat();
result.lng = results[0].geometry.location.lng();
} else {
result.lat = null;
result.lng = null;
}
});
}
}
function geocode_all() {
departure = geocode({
address: $('#departure')
});
//console.log(departure);
arrival = geocode({
address: $('#arrival')
});
//console.log(arrival);
}
I would like that my departure variable and my arrival variable to be object with the resulting latitude and longitude.
How should I proceed as my result variable is out of scope?
Thanks !
Upvotes: 0
Views: 123
Reputation: 1074295
The problem isn't that the function is anonymous, and it isn't scope; the problem is that the Google geolocation API is asynchronous. It's impossible for your geocode
function to return its result; instead, just like Google's function, it must accept a callback that it calls back with the result later, when the result is known. (Or it can use callbacks indirectly, via the "promise" pattern, but the fundamental concept is the same.)
So, using a callback:
function geocode(options, callback) {
// ^--- Accept the callback
var address = options.address.val() || null;
var result = {};
if (address) {
geocoder.geocode( { 'address': address }, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
result.lat = results[0].geometry.location.lat();
result.lng = results[0].geometry.location.lng();
} else {
result.lat = null;
result.lng = null;
}
callback(result); // <== Call it
});
}
}
// usage
geocode({/*...*/}, function(result) {
// This gets called later, asynchronously, with the result
});
Or using a jQuery Deferred
/Promise
:
function geocode(options) {
var d = new $.Deferred(); // <== Create the deferred
var address = options.address.val() || null;
var result = {};
if (address) {
geocoder.geocode( { 'address': address }, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
result.lat = results[0].geometry.location.lat();
result.lng = results[0].geometry.location.lng();
} else {
result.lat = null;
result.lng = null;
}
// Resolve the Deferred using your result
d.resolve(result);
});
}
// Return the Promise for the Deferred
return d.promise();
}
// Usage
geocode({/*....*/}).done(function(result) {
// This gets called later, asynchronously, with the result
});
Upvotes: 1