Reputation: 2736
I want to convert this piece of code that I made into a promise
because I want to show the geocoded address into vuetify
this is my code so far, I'm including google maps api and lodash .
<!DOCTYPE html>
<html>
<head>
<title>Reverse Geocoding Sample</title>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
<script>
function geocodelatLng(){
var response = [
{
"address": "213 Marlon Forks\nSouth Corineland, HI 81723-1044",
"lat": "10.30431500",
"lng": "123.89035500"
},
{
"address": "1291 Stephania Road\nLake Dorotheastad, TN 82682-76",
"lat": "10.30309100",
"lng": "123.89154500"
},
{
"address": "20330 Schmeler Course Apt. 210\nNorth Ari, NV 70048",
"lat": "10.30356400",
"lng": "123.89964100"
}
] ;
return _.map(response,coords => {
// console.log(arr.index);
var geocoder = new google.maps.Geocoder;
var latLng = {
lat : parseFloat(coords.lat),
lng : parseFloat(coords.lng)
} ;
// for every lat,lng .
// console.log(latLng);
geocoder.geocode({'location': latLng},function (results,status){
if (status === 'OK') {
if (results[0]) {
console.log(results[0].formatted_address);
} else {
window.alert('No results found');
}
} else {
window.alert('Geocoder failed due to: ' + status);
}
});
});
}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyA6vKL6Q4u5ZhGAJlYOMkQZ13pxCUXOe9k&callback=geocodelatLng">
</script>
</body>
</html>
Now this logs everything into the console but my problem is that I dont know how to show it in the v-list-tile-title tag. I tried everything used promises but it won't work, maybe you can help me. Not familiar with es6 tho.
<v-list-tile>
<v-list-tile-content>
<v-list-tile-title>{{ geocodedCoordinates address here }}</v-list-tile-title>
<v-list-tile-sub-title>{{ address.address }}</v-list-tile-sub-title>
</v-list-tile-content>
</v-list-tile>
Upvotes: 1
Views: 1114
Reputation: 19298
On the basis that you want geocodelatLng()
to return a promise that delivers geocode results, you first need something that will convert geocoder.geocode()
from a callback API to Promises. The general principles of doing that are covered extensively here.
Following that advice, you might end up with something like this:
function geocodelatLng() {
var response = [ ....... ]; // as in the question
var promises = response.map(function(coords) { // map response to an array of Promises.
return new Promise(function(resolve, reject) {
var geocoder = new google.maps.Geocoder();
var latLng = {
'lat': parseFloat(coords.lat),
'lng': parseFloat(coords.lng)
};
geocoder.geocode({'location': latLng}, function(results, status) {
if (status === 'OK') {
if (results.length) {
resolve(results[0]); // or `resolve(results)` to deliver all results
} else {
reject(new Error('No results found'));
}
} else {
reject(new Error('Geocoder failed due to: ' + status));
}
});
});
});
return Promise.all(promises);
}
You are left with a possible issue that Promise.all()
will return a rejected promise if any one of the promises
rejects, which you probably don't want. It would be better to ignore rejections (errors) and deliver successfully derived results.
A solution to that issue is provided here in the form of a reflect
function, which can be applied as follows:
function geocodelatLng() {
var response = [ ....... ]; // as in the question
function reflect(promise) {
return promise.then(function(v) {
return { 'status':'resolved', 'value':value };
}, function(e) {
return { 'status':'rejected', 'error':e };
});
}
var promises = response.map(coords => { // map response to an array of Promises.
return new Promise(function(resolve, reject) {
var geocoder = new google.maps.Geocoder();
var latLng = {
'lat': parseFloat(coords.lat),
'lng': parseFloat(coords.lng)
};
geocoder.geocode({'location': latLng}, function(results, status) {
if (status === 'OK') {
if (results[0]) {
resolve(results[0]);
} else {
reject(new Error('No results found'));
}
} else {
reject(new Error('Geocoder failed due to: ' + status));
}
});
});
});
return Promise.all(promises.map(reflect)) // map `promises` to an array of "refelected" promises before passing to Promise.all()
.then(function(results) {
return results.filter(function(res) { // filter the reflected results to exclude errors
return res.status === 'resolved';
}).map(function(res) { // map the remaining reflected results to the value of interest
return res.value;
});
});
}
geocodelatLng's caller is now returned a Promise that will deliver (via .then()) all the successful geocode results, which can be passed to vuetify
or whatever.
Upvotes: 1