2

Ok guys, I know this topic has already been discussed multiple times, but I can't find an answer to solve my problem.

So I'm trying to do a simple think : I'm creating a string, like : distance is : " + CalculateDistance(position); The wanted result is something like distance is 5kms (8min).

CalculateDistance(position) is a function calling a Google maps API called DistanceMatrix to calculate distance between two points. The API is documented here, and the given sample perfectly works. I adapted it like this :

function CalculateDistance(position)
{
    var service = new google.maps.DistanceMatrixService();
    var destination = new google.maps.LatLng(/* some lat/lng */);

    service.getDistanceMatrix(
    {
        origins: [position],
        destinations: [destination],
        travelMode: google.maps.TravelMode.DRIVING,
        unitSystem: google.maps.UnitSystem.METRIC,
        avoidHighways: false,
        avoidTolls: false
    }, callback);
}

function callback(response, status) {
    if (status == google.maps.DistanceMatrixStatus.OK)
    {
        var origins = response.originAddresses;
        var destinations = response.destinationAddresses;

        var results = response.rows[0].elements;
        distanceMatrixResult = results[0].distance.text + " ( " + results[0].duration.text + " min)";
    }

Oh, by the way, distanceMatrixResult is a global variable. In fact, I just need to get the content of results[0].distance.text (and when I print it in the console in callback(), the value is OK) and then concatenate the value with "Distance is". If someone have a smarter solution, it is welcomed !

The API call is asynchronous, and in my case, distanceMatrixResult is always empty in the result string. But when I log its value in the console, distanceMatrixResult value became the good one AFTER the string was created.

All I want to write is :

• Call CalculateDistance (which call callback asynchronously)
• When callback is ended, concatenate the string with the distanceMatrixResult value.

I tried some Deferred, like $.done() and $.when().then() but I can't success...

Can someone help me ?
Thank you !

AlexB
  • 7,302
  • 12
  • 56
  • 74

1 Answers1

8

distanceMatrixResult is a global variable

It should not, it should be the value which your Promise (Deferred) stands for. This is the basic setup:

function calculateDistance(position) {
    var service = new google.maps.DistanceMatrixService();
    var destination = new google.maps.LatLng(/* some lat/lng */);
    var dfd = $.Deferred();
    service.getDistanceMatrix({
        origins: [position],
        destinations: [destination],
        travelMode: google.maps.TravelMode.DRIVING,
        unitSystem: google.maps.UnitSystem.METRIC,
        avoidHighways: false,
        avoidTolls: false
    }, function(response, status) {
        if (status == google.maps.DistanceMatrixStatus.OK)
            dfd.resolve(response);
        else
            dfd.reject(status);
    });
    return dfd.promise();
}

Now, you want to do

calculateDistance(…).then(function(response) {
    var origins = response.originAddresses;
    var destinations = response.destinationAddresses;
    var results = response.rows[0].elements;
    return results[0].distance.text + " ( " + results[0].duration.text + " min)";
}).done(function(distanceMatrixResult) {
    var myString = "distance is: "+distanceMatrixResult;
    // do something with your string now
});
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • I'd like to say an ENORMOUS thank you @Bergi, the value in mystring is the good one, thank you so much !! Still have some things to do in order everything works properly, but your answer will allow me to progress and better understand Deferred. – AlexB Oct 01 '13 at 21:52
  • Sorry to ask you directly another question, I'd like to call `calculateDistance()` THREE times and concatenates the results of DistanceMatrix API in `myString`. I tried som `for` loop but I always have the FIRST result in `myString`... Do you know how to achieve this @Bergi ? – AlexB Oct 03 '13 at 15:23
  • I'm not sure what you have done exactly, but you might need to [look into closures for (async) callbacks that are called after the loop](http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example), and at [`$.when`](http://api.jquery.com/jQuery.when/) about waiting for multiple promises to resolve. If those links didn't help, please post another question with your code. – Bergi Oct 04 '13 at 09:52