Adam
Adam

Reputation: 3

JavaScript async help - Google Maps JavaScript API to calculate directions

I am fairly new to JavaScript, so here's a summary of my problem for context. The user enters two locations, originInput and destinationInput. The Places API then gets the Latlng for the locations, which works as expected. My problem comes when trying to use these results to calculate the directions between the two. As far as I can tell, the problem is that the calcRoute function is executing before the Places objects are returned from the Places API, which takes time. I don't know how to get around this, assuming that is the problem.

So far, I have tried to append the value that is returned from the Places API to an array, then use this as a parameter for the Directions API.

HTML:

<input type="text" id="originInput"></input>
<input type="text" id="destinationInput"></input>
<button onclick="initMap()"></button> 

<div id="map"></div>

Relevant JS:

// function takes user input and gets back a place object from the API
function getPlaces() {
  var originInput = document.getElementById("originInput");
  var destinationInput = document.getElementById("destinationInput");
  var requests = {
    request1: {
      query: originInput.value,
      fields: ['name', 'geometry']
    },
    request2: {
      query: destinationInput.value,
      fields: ['name', 'geometry']
    }
  };
  placeService.findPlaceFromQuery(requests.request1, callback);
  placeService.findPlaceFromQuery(requests.request2, callback);
  // Calls calcRoute function to display the route between points
  calcRoute(resultsLatlng[0], resultsLatlng[1]);
}

// callback function for findPlaceFromQuery
function callback(results, status) {
  if (status === google.maps.places.PlacesServiceStatus.OK) {
    resultsLatlng.push(results[0].geometry.location);
    console.log(resultsLatlng)
    }
  }

  // Function to access the directionsService API and display the route
function calcRoute(start, end) {
  var request = {
    origin: start,
    destination: end,
    travelMode: 'DRIVING'
  }
  directionsService.route(request, function(results, status) {
    if (status == 'OK') {
      directionsRenderer.setDirections(result)
      console.log(result)
    }
  })
  console.log(resultsLatlng)
}

See https://jsfiddle.net/adam1lake/qjcou20h/ for the code. Just put your API key in the script tag at the bottom of the HTML and it should work.

If you run the code on the jsfiddle, there will be an error as the directions API isn't receiving a Latlng object as its parameters for start and end location. Please feel free to correct any of my other code on that jsfiddle :)

Upvotes: 0

Views: 360

Answers (1)

Kevin Guebert
Kevin Guebert

Reputation: 306

The problem here is dealing with callbacks, asynchronous code, and knowing when the data will be returned. You are correct when you say that the calcRoute is executing before the Places object is returned. There are some great resources on understanding asynchronous javascript to read and research.

One way to fix that would be to update your callback function to check how many elements exist in your resultsLatlng array. If it has two elements (the start location and the end location), then calculate the route from the results.

// callback function for findPlaceFromQuery
function callback(results, status) {
  if (status === google.maps.places.PlacesServiceStatus.OK) {
    resultsLatlng.push(results[0].geometry.location);
    if (resultsLatlng.length == 2) { // New code
      calcRoute(resultsLatlng[0], resultsLatlng[1]);
    }
  }
}

Upvotes: 0

Related Questions