I have a function for geocoding an address that returns the name of the city of the same address
// geocode the given address
geocodeAddress(address, callback) {
this.mapsAPILoader.load().then(() => {
var geocoder = new google.maps.Geocoder();
geocoder.geocode({ 'address': address }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
results[0].address_components.forEach(arrAddress => {
if (arrAddress.types[0] == "locality") {
callback(arrAddress.long_name);
}
})
} else {
console.log("Geocode was not successful for the following reason: " + status);
}
});
});
};
when I call that function and want to print the city name it is printed 'undefined' from the code line below the geocodeAddress function and after that is printed properly city name
this.geocodeAddress(this.offerAddress, data => {
this.hostCity = data;
console.log(this.hostCity);
});
console.log(this.hostCity);
I was trying to add some timeout before second console.log function but without any success
therefore, I'm interested how to access this value after returning data from geocoder because I need to use this data for storing in database and if I try to store like this
this.geocodeAddress(this.offerAddress, data => {
this.hostCity = data;
this.service.addData({"address": this.offerAddress, "city": this.hostCity}, "/data")
.subscribe(data => {
this.router.navigate(['list']);
})
});
it store data but router.navigate not working properly
so I need solution for accessing hostCity outside of geocodeAddress callback function, or how to properly call some another function inside this geocodeAddress callback function
If you're using TypeScript, you can make your geocodeAddress
method return a Promise
, instead of using callbacks, and then use async/await
:
async geocodeAddress(address): Promise<string[]> {
return new Promise((resolve, reject) => {
this.mapsAPILoader.load().then(() => {
var geocoder = new google.maps.Geocoder();
geocoder.geocode({ 'address': address }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
const result: string[] = [];
results[0].address_components.forEach(arrAddress => {
if (arrAddress.types[0] == "locality") {
result.push(arrAddress.long_name);
}
});
resolve(results);
} else {
console.log("Geocode was not successful for the following reason: " + status);
reject(status);
}
});
});
});
};
Now, this function returns an array with the long names of all the addresses you were seeking. To use it:
const data: string[] = await this.geocodeAddress(this.offerAddress);
this.hostCity = data[0];
// do whatever you want now
This way you get the benefits of asynchronous programming, with the simplicity of synchronous one.