0

I want the distance by car and train. I can get it from the Google Maps API but when I want the distance in a variable, the function getDistance() with the API returns direct and doesn't wait on the response from the API. On the Internet I found solutions with async/await, promises and callbacks. But it doesn't work for me, probably because I wrote it wrong. But can someone please help me and explain my fault?

Thanks!

My code:

function giveComparing(result) {
        var $distanceCar = getDistance(result, google.maps.TravelMode.DRIVING);
        var $distanceTrain = getDistance(result, google.maps.TravelMode.TRANSIT);

        console.log($distanceCar); // Output: 0
        console.log($distanceTrain);  // Output: 0

    };

    function getDistance(result, transport) {
        var origin = result.departure.stationinfo.locationY + ',' + result.departure.stationinfo.locationX;
        var destination = result.arrival.stationinfo.locationY + ',' + result.arrival.stationinfo.locationX;
        var service = new google.maps.DistanceMatrixService();
        var distance = 0;

        service.getDistanceMatrix(
            {
                origins: [origin],
                destinations: [destination],
                travelMode: [transport]
            }, callback);

        function callback(response, status) {
            console.log(response.rows[0].elements[0].distance.value);
            distance = response.rows[0].elements[0].distance.value;
        };
        return distance;            
  } 

Output

Sarah De Cock
  • 87
  • 1
  • 2
  • 10
  • 3
    Welcome to SO. You should add your code to the question. In answer to your question the callback should be a function you _pass into_ `getDistance`, not a function inside it. [See the section on callbacks in the upvoted answer here](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call). – Andy Dec 06 '18 at 14:21
  • It is in de picture (link: my code) because first i thought stackoverflow would show it. But thanks I will put in in the text! – Sarah De Cock Dec 06 '18 at 14:25

2 Answers2

0

As you mentioned you are right on point, you do need to use promise and async/await. A previews question was solved, which are quite similar and well explained here if you want an indepth explanation :)

You can do the following to achieve the effect you are looking for:

async function giveComparing(result) {
  try{
    var $distanceCar = await getDistance(result, google.maps.TravelMode.DRIVING); //Wait for the promise to resolve
    var $distanceTrain = await getDistance(result, google.maps.TravelMode.TRANSIT);//Wait for the promise to resolve

    console.log($distanceCar);
    console.log($distanceTrain); 
  }catch(){
    console.log("Promise was rejected") //A promise was rejected.
  }
};

function getDistance(result, transport) {
  return new Promise((resolve, reject) => {
    var origin = result.departure.stationinfo.locationY + ',' + result.departure.stationinfo.locationX;
    var destination = result.arrival.stationinfo.locationY + ',' +      result.arrival.stationinfo.locationX;
    var service = new google.maps.DistanceMatrixService();

    service.getDistanceMatrix(
      {
        origins: [origin],
        destinations: [destination],
        travelMode: [transport]
      }, callback);

    function callback(response, status) {
        if(status == "OK"){
            console.log(response.rows[0].elements[0].distance.value);
            let distance = response.rows[0].elements[0].distance.value;
            resolve(distance); //Resolve our promise with the distance.
        }else{
            reject(); //Reject the promise since the status return anything else then OK
        }
    }
  });        
} 

The above code is not directly tested however I think the status OK is correct, found it from their developer guide.

jonaslagoni
  • 663
  • 7
  • 23
  • Thank you very much! I tried also return new Promise but I dit it on service.getDistanceMatrix but that didn't work .It's nice to see that i was on the right track. Thank you! – Sarah De Cock Dec 06 '18 at 14:50
0

You almost had it right. You can't return a value from an async operation like that so you use a callback, but you pass that callback into getDistance as an argument to be called instead.

function getDistance(result, transport, callback) {

 //... 

  service.getDistanceMatrix({
    origins: [origin],
    destinations: [destination],
    travelMode: [transport]
  }, callback);
}

// Call getDistance, passing the original arguments
// and a callback function
getDistance(result, transport, function (response) {
  const distance = response.rows[0].elements[0].distance.value;
});
Andy
  • 61,948
  • 13
  • 68
  • 95