Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get distances from Google maps javascript api v3

I'm trying to sort through an array of distances generated by google maps. I need to order my list, closest to furthest. I can get all of the directions and distances displayed just fine with the directionsService api example, but I cannot figure out how to retrieve that info outside of the function so that I can sort it.

    function calcDistances() {
    for (var x = 0; x < wineries.length; x++) {
        var winery = wineries[x];
        var trdistances = [];       
        var request = {
            origin: map.getCenter(), 
            destination: new google.maps.LatLng(winery[1], winery[2]),
            travelMode: google.maps.DirectionsTravelMode.DRIVING
        };

        directionsService.route(request, function(response, status) {
            if (status == google.maps.DirectionsStatus.OK) {
                var route = response.routes[0];
                var summaryPanel = document.getElementById("tasting_rooms_panel");
                // For each route, display summary information.
                for (var i = 0; i < route.legs.length; i++) {
                    //this works fine and displays properly
                    summaryPanel.innerHTML += route.legs[i].distance.text;
                    //I want to store to this array so that I can sort
                    trdistances.push(route.legs[i].distance.text);
                }
            }
        });
        alert(trdistances[0]);//debug
    }
}

As commented in the code, I can populate summaryPanel.innerHTML, but when I populate the array trdistances, the alert gives me "undefined". Is this some rookie javascript coding error? I read up on the scope of variables and this should work. Help me oh wise ones.

like image 250
Poolczar Avatar asked Aug 23 '26 15:08

Poolczar


1 Answers

function calcDistances() {
    for (var x = 0; x < wineries.length; x++) {
        var winery = wineries[x];
        var trdistances = [];       
        var request = {
            origin: map.getCenter(), 
            destination: new google.maps.LatLng(winery[1], winery[2]),
            travelMode: google.maps.DirectionsTravelMode.DRIVING
        };

        //Using Closure to get the right X and store it in index
        (function(index){
               directionsService.route(request, function(response, status) {
                    if (status == google.maps.DirectionsStatus.OK) {
                         var route = response.routes[0];
                         var summaryPanel = document.getElementById("tasting_rooms_panel");
                         // For each route, display summary information.
                         for (var i = 0; i < route.legs.length; i++) {
                              //this works fine and displays properly
                              summaryPanel.innerHTML += route.legs[i].distance.text;
                              //I want to store to this array so that I can sort
                              trdistances.push(route.legs[i].distance.text);
                         }

                         if(index == wineries.length-1){  //check to see if this is the last x callback
                              console.log(trdistances); //this should print the result 
                              //or in your case you can create  global function that gets called here like sortMahDistance(trdistances); where the function does what you want.
                              printMyDistances(trdistances); //calls global function and prints out content of trdistances console.log();
                         }
                    }
               });
        })(x);  //pass x into closure as index
    }
}

//on global scope
function printMyDistances(myArray){
     console.log(myArray);
}

The problem is scope to keep track of the for loop's X. Basically, you have to make sure all the callbacks are done before you can get the final result of trdistances. So, you'll have to use closure to achieve this. By storing first for loops' X into index within closure by passing X in as index, you can check to see if the callback is the last one, and if it is then your trdistances should be your final result. This mod of your code should work, but if not please leave comment.

Furthermore, I marked up my own version of google map using closure to resolve using async directionServices within for loop, and it worked. Here is my demo jsfiddle. Trace the output of console.log(); to see X vs index within the closure.

like image 178
KJYe.Name Avatar answered Aug 26 '26 06:08

KJYe.Name