TheBAST
TheBAST

Reputation: 2736

How to convert into promise and geocode the address with google maps

I want to convert this piece of code that I made into a promise

because I want to show the geocoded address into vuetify

enter image description here

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

Answers (1)

Roamer-1888
Roamer-1888

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

Related Questions