Ellinor Ellinor - 1 month ago 13
Javascript Question

Google Maps Infowindow with dynamic data

I am using Google distance matrix to calculate distances between different destinations at the same time. I have one origin and several destinations and I want to be able to add infowindows with this data (the distance to destination). The result I am getting at the moment is that the address is undefined. This is because it is outside the for loop, but I am unsure on how to fix this.

My code:

function callback(response, status) {
if(status=="OK") {
var originList = response.originAddresses;
var destinationList = response.destinationAddresses;
var bounds = new google.maps.LatLngBounds;
var outputDiv = document.getElementById('output');

var showGeocodedAddressOnMap = function(asDestination) {
var icon = asDestination ? destinationIcon : originIcon;
return function(results, status) {
if (status === 'OK') {
map.fitBounds(bounds.extend(results[0].geometry.location));
var markersArray = new google.maps.Marker({
map: map,
position: results[0].geometry.location,
icon: icon
});

google.maps.event.addListener(markersArray, 'click', function () {
infowindow.setContent('<strong>Address</strong><br /><br />' + destinationList[j] + '<br /><br /><strong>Distance:</strong> ');
infowindow.open(map, this);
});

} else {
alert('Geocode was not successful due to: ' + status);
}
};
};

for (var i = 0; i < originList.length; i++) {
var results = response.rows[i].elements;
geocoder.geocode({'address': originList[i]},
showGeocodedAddressOnMap(false));
for (var j = 0; j < results.length; j++) {
geocoder.geocode({'address': destinationList[j]}, showGeocodedAddressOnMap(true));

/*outputDiv.innerHTML += originList[i] + ' to ' + destinationList[j] +
': ' + results[j].distance.text + '<br>';*/

}
}

} else {
alert("Error: " + status);
}
}

Answer

One option is to get function closure on the address in the showGeocodedAddressOnMap function.

var showGeocodedAddressOnMap = function(address, asDestination) {
  return function(results, status) {
    if (status === 'OK') {
      map.fitBounds(bounds.extend(results[0].geometry.location));
      var markersArray = new google.maps.Marker({
        map: map,
        position: results[0].geometry.location,
        // icon: icon
      });
      google.maps.event.addListener(markersArray, 'click', function(evt) {
        infowindow.setContent('<strong>Address</strong><br /><br />' + address + '<br /><br /><strong>Distance:</strong> ');
        infowindow.open(map, this);
      });
    } else {
      alert('Geocode was not successful due to: ' + status);
    }
  };
};

proof of concept fiddle

code snippet:

function initialize() {
  map = new google.maps.Map(
    document.getElementById("map_canvas"), {
      center: {
        lat: 55.53,
        lng: 9.4
      },
      zoom: 10,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    });

  var service = new google.maps.DistanceMatrixService;
  service.getDistanceMatrix({
    origins: [origin1, origin2],
    destinations: [destinationA, destinationB],
    travelMode: 'DRIVING',
    unitSystem: google.maps.UnitSystem.METRIC,
    avoidHighways: false,
    avoidTolls: false
  }, callback);
}

function callback(response, status) {
  if (status == "OK") {
    var originList = response.originAddresses;
    var destinationList = response.destinationAddresses;
    var bounds = new google.maps.LatLngBounds;
    var outputDiv = document.getElementById('output');

    var showGeocodedAddressOnMap = function(address, asDestination) {
      return function(results, status) {
        if (status === 'OK') {
          map.fitBounds(bounds.extend(results[0].geometry.location));
          var markersArray = new google.maps.Marker({
            map: map,
            position: results[0].geometry.location,
          });
          google.maps.event.addListener(markersArray, 'click', function(evt) {
            infowindow.setContent('<strong>Address</strong><br /><br />' + address + '<br /><br /><strong>Distance:</strong> ');
            infowindow.open(map, this);
          });
        } else {
          alert('Geocode was not successful due to: ' + status);
        }
      };
    };

    for (var i = 0; i < originList.length; i++) {
      var results = response.rows[i].elements;
      geocoder.geocode({
          'address': originList[i]
        },
        showGeocodedAddressOnMap(originList[i], false));
      for (var j = 0; j < results.length; j++) {
        geocoder.geocode({
          'address': destinationList[j]
        }, showGeocodedAddressOnMap(destinationList[j], true));
      }
    }
  } else {
    alert("Error: " + status);
  }
}
google.maps.event.addDomListener(window, "load", initialize);

var geocoder;
var map;
var origin1 = {
  lat: 55.93,
  lng: -3.118
};
var origin2 = 'Greenwich, England';
var destinationA = 'Stockholm, Sweden';
var destinationB = {
  lat: 50.087,
  lng: 14.421
};
var geocoder = new google.maps.Geocoder();
var infowindow = new google.maps.InfoWindow();
html,
body,
#map_canvas {
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map_canvas"></div>

Comments