AChic
AChic

Reputation: 35

Rendering routes with GoogleAPI JS

I was following along with a tutorial involving the GoogleMaps API JS, and everything went well. When trying to building my own app I've come across an issue with displaying a route. The application I'm working on is mainly written in ruby on rails.

The "pseudo code" problem is when clicking on to "view route" button, the route is not displaying on the map.

Below is the HTML that triggers the first event when clicking on the search with in time button, and the CSS as requested.

<body>
 <div>
    <span class="text"> Within </span>
    <select id='max-duration'>
      <option value="10">10 min</option>
    </select>
    <select id="mode">
      <option value="DRIVING">drive</option>
    </select>
    <span class="text">of</span>
    <input id= 'search-within-time-text' type='text' placeholder='Your Location'>
    <input id= 'search-within-time' type='button' value='Go'>
  </div>
 <div id="map"></div>
 <script src="https://maps.googleapis.com/maps/api/js?libraries=places,drawing,geometry&key=<%= ENV["MAP_API"] %>&v=3"></script>
</body>

<style>
  #map {
   bottom: 0px;
   height: 500px;
   left: 362px;
   position: absolute;
   right: 0px;
  }

 .container {
  height: 500px;
  position: relative;
 }

 .options-box {
  background: #fff;
  border: 1px solid black;
  height: 91.75%;
  line-height: 35px;
  padding: 10px 10px 30px 10px;
  text-align: left;
  width: 340px;
 }

 #zoom-to-area-text{
  width:200px;
 }
</style>

The location array that is stroing the data is found in the maps controller, where we are pushing data from our SQLite DB.

def index
@test_array = []
@test.each do |h|
  @test_array.push({lat: h.lat, lng: h.lng})
  end
end

In particular I believe the problem lays within the function displayDirections. Which can be found at the bottom of the full code

The displayDirections function is written outside of the initMap function, because of a scoping issue when it is written inside of the initMap function. I've read the problem below

Maybe a similar issue

But had issues with displayDirections being defined at the click event, when it was written with in the initMap function, in the function displayMarkersWithinTime.

Any help is appreciated! Thanks!

function initMap() {
 var map;
 var markers = [];
 var placeMarkers = [];

 document.getElementById('search-within-time').addEventListener('click', function(){
  searchWithinTime();
 });

 map = new google.maps.Map(document.getElementById('map'), {
  center: {lat: 39.9523789, lng: -75.1635996},
  zoom: 13,
  mapTypeControl: false
 });   

 var locations = <%= raw @test_array.to_json%>

 for (var i = 0; i < locations.length; i++) {
  var position = locations[i]
  var marker = new google.maps.Marker({
   position: position,
   animation: google.maps.Animation.DROP,
   id: i
   });
   markers.push(marker); 
  } 

 function hideMarkers(markers) {
  for (var i = 0; i < markers.length; i++){
   markers[i].setMap(null);
  }
 }

 function searchWithinTime(){
  var distanceMatrixService = new google.maps.DistanceMatrixService;
  var address = document.getElementById('search-within-time-text').value;
  if (address == ''){
   window.alert('You must enter an address.');
  } else {
   hideMarkers(markers);
   var origins = [];
   for (var i = 0; i < markers.length; i++) {
    origins[i] = markers[i].position;
   }
   var destination = address;
   var mode =  document.getElementById('mode').value;
   distanceMatrixService.getDistanceMatrix({
     origins: origins,
     destinations: [destination],
     travelMode: google.maps.TravelMode[mode],
     unitSystem: google.maps.UnitSystem.IMPERIAL,
   }, function(response, status) {
     if (status !== google.maps.DistanceMatrixStatus.OK) {
       window.alert('Error was: ' + status);
     } else {
       displayMarkersWithinTime(response);
     }
   });
  }
 }

 function displayMarkersWithinTime(response){
  var maxDuration = document.getElementById('max-duration').value;
  var origins = response.originAddresses;
  var destinations = response.destinationAddresses;
  var atLeastOne = false; 
  for (var i = 0; i < origins.length; i++) {
   var results = response.rows[i].elements;
    for (var j = 0; j < results.length; j++) {
     var element = results[j];
     if (element.status === "OK") {
      var distanceText = element.distance.text;
      var duration = element.duration.value / 60;
      var durationText = element.duration.text;
      if (duration <= maxDuration) {
        markers[i].setMap(map);
        atLeastOne = true;
        var infowindow = new google.maps.InfoWindow({
          content : durationText + ' away, ' + distanceText + '<div><input type=\"button\" value=\"View Route\" onclick =' + '\"displayDirections(&quot;' + origins[i] + '&quot;);\"</input></div>'
        });
        infowindow.open(map, markers[i]);
        // if user clicks on marker close the small info window to open a new
        markers[i].infowindow = infowindow;
        google.maps.event.addListener(markers[i], 'click', function (){
          this.infowindow.close();
        });
      }
    }
  }
 }
 if(!atLeastOne) {
   window.alert('We could not find any locations within that distance');
 }
 console.log("hello") 
 } 
}

var map;
var markers = [];
map = new google.maps.Map(document.getElementById('map'), {
 center: {lat: 39.9523789, lng: -75.1635996},
 zoom: 13,
 mapTypeControl: false
});   

function hideMarkers(markers) {
 for (var i = 0; i < markers.length; i++){
  markers[i].setMap(null);
 }
}

 function displayDirections(origin) {
  hideMarkers(markers);
  var directionsService = new google.maps.DirectionsService;
  var destinationAddress = document.getElementById('search-within-time-text').value;
  var mode = document.getElementById('mode').value;
  directionsService.route({
   origin: origin,
   destination: destinationAddress,
   travelMode: google.maps.TravelMode[mode]
  }, function(response, status) {
  console.log(response)
  console.log(status)
  if (status === google.maps.DirectionsStatus.OK) {
    var directionsDisplay = new google.maps.DirectionsRenderer({
      map: map,
      directions: response,
      draggable: true,
      polylineOptions: {
        strokeColor: 'black'
      }
     }, console.log(map), console.log(response));
    } else {
     window.alert('Directions request failed due to ' + status);
    }
   });
   console.log("testing")
  }
 google.maps.event.addDomListener(window, initMap())

Upvotes: 1

Views: 85

Answers (1)

geocodezip
geocodezip

Reputation: 161334

Your (initialized) map variable is local to the initMap function. Make it global.

Change:

function initMap() {
  var map;
  // ...

To:

var map;
function initMap() {

proof of concept fiddle

code snippet:

var map;

function initMap() {
  var markers = [];
  var placeMarkers = [];
  var titles;
  var latitudes;
  var longitudes;

  var directionsDisplay = new google.maps.DirectionsRenderer();
  directionsDisplay.setMap(map);

  document.getElementById('show-listings').addEventListener('click', showListings);
  document.getElementById('hide-listings').addEventListener('click', function() {
    hideMarkers(markers);
  });

  document.getElementById('search-within-time').addEventListener('click', function() {
    searchWithinTime();
  });

  var timeAutocomplete = new google.maps.places.Autocomplete(
    document.getElementById('search-within-time-text'));

  map = new google.maps.Map(document.getElementById('map'), {
    center: {
      lat: 39.9523789,
      lng: -75.1635996
    },
    zoom: 13,
    mapTypeControl: false
  });

  var locations = [{
      lat: 39.952584,
      lng: -75.165222
    }, {
      lat: 47.6062095,
      lng: -122.3320708
    },
    {
      lat: 34.0522342,
      lng: -118.2436849
    },
    {
      lat: 39.114053,
      lng: -94.6274636
    }, {
      lat: 25.7616798,
      lng: -80.1917902
    }
  ];

  for (var i = 0; i < locations.length; i++) {
    var position = locations[i]
    var marker = new google.maps.Marker({
      position: position,
      animation: google.maps.Animation.DROP,
      id: i,
      map: map
    });
    markers.push(marker);
  }

  function showListings() {
    var bounds = new google.maps.LatLngBounds();
    for (var i = 0; i < markers.length; i++) {
      markers[i].setMap(map);
      bounds.extend(markers[i].position);
    }
    map.fitBounds(bounds);
  }

  function hideMarkers(markers) {
    for (var i = 0; i < markers.length; i++) {
      markers[i].setMap(null);
    }
  }

  function searchWithinTime() {
    var distanceMatrixService = new google.maps.DistanceMatrixService();
    var address = document.getElementById('search-within-time-text').value;
    if (address == '') {
      window.alert('You must enter an address.');
    } else {
      hideMarkers(markers);
      var origins = [];
      for (var i = 0; i < markers.length; i++) {
        origins[i] = markers[i].position;
      }
      var destination = address;
      var mode = document.getElementById('mode').value;
      distanceMatrixService.getDistanceMatrix({
        origins: origins,
        destinations: [destination],
        travelMode: google.maps.TravelMode[mode],
        unitSystem: google.maps.UnitSystem.IMPERIAL,
      }, function(response, status) {
        if (status !== google.maps.DistanceMatrixStatus.OK) {
          window.alert('Error was: ' + status);
        } else {
          displayMarkersWithinTime(response);
        }
      });
    }
  }

  function displayMarkersWithinTime(response) {
    var maxDuration = document.getElementById('max-duration').value;
    var origins = response.originAddresses;
    var destinations = response.destinationAddresses;
    var atLeastOne = false;
    for (var i = 0; i < origins.length; i++) {
      var results = response.rows[i].elements;
      for (var j = 0; j < results.length; j++) {
        var element = results[j];
        if (element.status === "OK") {
          var distanceText = element.distance.text;
          var duration = element.duration.value / 60;
          var durationText = element.duration.text;
          if (duration <= maxDuration) {
            markers[i].setMap(map);
            atLeastOne = true;
            var infowindow = new google.maps.InfoWindow({
              content: durationText + ' away, ' + distanceText + '<div><input type=\"button\" value=\"View Route\" onclick =' + '\"displayDirections(&quot;' + origins[i] + '&quot;);\"</input></div>'
            });
            infowindow.open(map, markers[i]);
            // if user clicks on marker close the small info window to open a new
            markers[i].infowindow = infowindow;
            google.maps.event.addListener(markers[i], 'click', function() {
              this.infowindow.close();
            });
          }
        }
      }
    }
    if (!atLeastOne) {
      window.alert('We could not find any locations within that distance');
    }
    console.log("hello")
  }
}

var map;
var markers = [];
map = new google.maps.Map(document.getElementById('map'), {
  center: {
    lat: 39.9523789,
    lng: -75.1635996
  },
  zoom: 13,
  mapTypeControl: false
});

function hideMarkers(markers) {
  for (var i = 0; i < markers.length; i++) {
    markers[i].setMap(null);
  }
}

function displayDirections(origin) {
  hideMarkers(markers);
  var directionsService = new google.maps.DirectionsService();
  var destinationAddress = document.getElementById('search-within-time-text').value;
  var mode = document.getElementById('mode').value;
  directionsService.route({
    origin: origin,
    destination: destinationAddress,
    travelMode: google.maps.TravelMode[mode]
  }, function(response, status) {
    console.log(response)
    console.log(status)
    if (status === google.maps.DirectionsStatus.OK) {
      var directionsDisplay = new google.maps.DirectionsRenderer({
        map: map,
        directions: response,
        draggable: true,
        polylineOptions: {
          strokeColor: 'black'
        }
      }, console.log(map), console.log(response));
    } else {
      window.alert('Directions request failed due to ' + status);
    }
  });
  console.log("testing")
}
google.maps.event.addDomListener(window, 'load', initMap)
html,
body,
#map {
  height: 100%;
  width: 100%;
  padding: 0px;
  margin: 0px;
  background-color: white;
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry,places&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<input type="button" value="search" id="search-within-time" />
<input type="text" value="coffee" id="search-within-time-text" />
<input type="button" value="Show" id="show-listings" />
<input type="button" value="Hide" id="hide-listings" />
<input type="text" value="DRIVING" id="mode" />
<input type="text" value="1200" id="max-duration" />
<div id="map"></div>

Upvotes: 1

Related Questions