-1

I am trying to add 3 markers to a map and when click on the markers, an info window will be shown. But every array element inside google.maps.event.addListener becomes undefined.

What's the problem?

<div id="map-canvas2" style="width:100%;height:500px"></div>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script>
<script>
 var num;
 var marker;
 var infoWindow;
 var infoText;
 var lat;
 var lng;
 var map;

 function initialize() {
   num = 3;
   marker = [];
   infoWindow = [];
   infoText = [];
   lat = [];
   lng = [];

   infoText[0] = "test1";
   lat[0] = 22.420845;
   lng[0] = 114.208705; 
   infoText[1] = "test2";
   lat[1] = 22.416026;
   lng[1] = 114.209321; 
   infoText[2] = "test3";
   lat[2] = 22.420841;
   lng[2] = 114.205188; 
   for (var i = 0; i < num; i++) {
     marker[i]=new google.maps.Marker({
       position:new google.maps.LatLng(lat[i], lng[i]),
     });
     infoWindow[i] = new google.maps.InfoWindow({
       content:"<div>"+infoText[i]+"</div>"
     });
   }
   var mapOptions = {
     zoom: 17,
     center: new google.maps.LatLng(22.420458,114.207482)
   };
   map = new google.maps.Map(document.getElementById('map-canvas2'), mapOptions);

   for (var i = 0; i < num; i++) {
     marker[i].setMap(map);   
     google.maps.event.addListener(marker[i], 'click', function() {
       new google.maps.InfoWindow({
     content:"<div>"+infoText[i]+"</div>"
       }).open(map,marker[i]);
     });
   }
 }

 google.maps.event.addDomListener(window, 'load', initialize);
</script>
Unihedron
  • 10,902
  • 13
  • 62
  • 72
yulapshun
  • 3
  • 1

2 Answers2

0

Don't send indexed parameters to an anonymous function:

for (var i = 0; i < num; i++) {
 var mrk = marker[i];
 var iwContent = infoText[i];
 mrk.setMap(map);   
 google.maps.event.addListener(mrk, 'click', function() {
   new google.maps.InfoWindow({
 content:"<div>"+iwContent+"</div>"
   }).open(map,mrk);
 });
}
Sanon
  • 1
  • 1
0

The problem: Each event listener is referencing the same variable i which gets incremented on each pass of the for loop. So after the loop is finished the value of i is 3, but none of your arrays have an index of 3 so you get undefined. Because each event handler is referencing the same i variable they are all referencing the same undefined array values.

The solution: Create a closure so that the event handler for each marker has a it's own variable instead sharing reference to single variable.

for (var i = 0; i < num; i++) {
    marker[i].setMap(map);   
    google.maps.event.addListener(marker[i], 'click', (function(index) {
        return function() {
            new google.maps.InfoWindow({
                content: "<div>"+infoText[index]+"</div>"
            }).open(map, marker[index]);
        }
    })(i));
}

What we're doing is creating a Immediately-Invoked Function Expression "IIFE". The IIFE has a parameter called index which is set to the value of i. Because variables have function scope, index belongs only to this function. Inside the IIFE we return a function that will do the actual work when the event is triggered, but it will reference index not i.

chriserwin
  • 1,222
  • 1
  • 10
  • 13