0

I have a javascript code which calculates the distance between the user's location and an array of fuzzy addresses. It uses the distance matrix from the google maps api if I am not wrong. On the success of the getDistanceMatrix function a callback function is asynchronously called. Now, I need to be able to pass a particular value to this call back function so that I am able to replace the corresponding table row.

function getDistance(position){
        origin = new google.maps.LatLng(parseFloat(position.coords.latitude),parseFloat(position.coords.longitude));
        for (var i=0;i<mpoints_arr.length;i++){ 
            destination = mpoints_arr[i][2];
            service = new google.maps.DistanceMatrixService();
            service.getDistanceMatrix(
                {
                    origins: [origin],
                    destinations: [destination],
                    travelMode: google.maps.TravelMode.DRIVING,
                    avoidHighways: false,
                    avoidTolls: false
                }, 
                callback(i)
            );
        }
    }
    function callback(response, status, j){
        if(status == "OK"){
            alert(response.rows[0].elements[0].distance.text);
            console.log(j);
            //rows[i].getElementsByTagName('td')[3].innerHTML = response.rows[0].elements[0].distance.text;
        } else {
            alert("Error: " + status);
        }
    }

However, the object 'j' is said to be undefined in the log. Awaiting a solution. Thanks.

Jones
  • 379
  • 3
  • 9
  • 23
  • I did go through that thread. However, the problem here is that the value of i keeps on changing. I want the (distance,i) combination to be preserved. Otherwise I will not know which element is to be replaced with which distance. Because of the asynchronous call, the value of i that is passed is stagnant at 10, that is all the asynchronous calls are getting called after the loop. – Jones Mar 17 '14 at 16:01
  • See http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example for that problem. – Felix Kling Mar 17 '14 at 16:35

1 Answers1

5

You need to alter your current callback function so that it creates a callback function and returns it.

function callback(j){
  return function(response, status) {
    if(status == "OK"){
        alert(response.rows[0].elements[0].distance.text);
        console.log(j);
        //rows[i].getElementsByTagName('td')[3].innerHTML = response.rows[0].elements[0].distance.text;
    } else {
        alert("Error: " + status);
    }
  }
}

By doing this, you're using a separate function to make (and preserve) a copy of the value of "i" in the loop back in the other function. This new version of "callback" returns the function that will be used as the actual callback by the service. Because the actual callback function uses that saved copy of the loop index, each such callback created will have it's own "j" and you get the effect you want.

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • Thanks a lot! that worked great. Can you please elaborate a little on what you did there? – Jones Mar 17 '14 at 16:19
  • @Jones sure - I'll extend the answer. – Pointy Mar 17 '14 at 16:27
  • Cool. So now, the response and state object variables that are passed into the returned function inside callback actually hold the response and state variables of the callback function itself. And since callback is called by the distancematrix function, we get the appropriate response object. Is that right? – Jones Mar 17 '14 at 17:46
  • 1
    Pointy, you rock. And roll. THANKS A BUNCH!!! Works perfectly. – Tom Hundley May 14 '15 at 21:25