Benjamin Kovach
Benjamin Kovach

Reputation: 3260

Google Maps event listeners not working properly in a Javascript 'for' loop

I'm trying to set up a Google map instance where some content is dynamically generated for a set of points.

Right now, I'm using a for loop to loop through any number of latitude and longitude values and create markers are those points on the map.

I'm trying to add info windows that correspond to each of these markers and have them pop up when you click the markers.

However, I'm having a little bit of trouble. It looks like my for loop that creates basically everything is working without fail, apart from the eventListener section:

function drawMap(points) {
    popUps = new Array();
    infoWindows = new Array();
    positions = new Array();

    contents = '<div id = "content">' +
        '<div id="siteNotice">' +
        '</div>' +
        '<p id="firstHeading" class="firstHeading">Position</h1>' +
        '</div>';

    infowindow = new google.maps.InfoWindow({
        content: contents
    });

    for( i = 0; i < points.length; i++ ){
        positions[i] = new google.maps.Marker({ position: 
        latlng[i], 
        map:map, 
        title:"Position"});

        popUps[i] = '<div id = "content">' +
            '<div id="siteNotice">' +
            '</div>' +
            '<p id="firstHeading" class="firstHeading">Position</h1>' +
            '</div>';

        infoWindows[i] = new google.maps.InfoWindow({
            content: popUps[i]
        });

    // everything up to this point works fine, I can reference it all manually
    // and get back the expected value.

        google.maps.event.addListener(positions[i], 'click', function(){
            infoWindows[i].open(map, positions[i]);                 
        });

    // if I change each instance of "i" to "0" here, I'll get a popup on the
    // expected marker containing content that I defined in this for loop. Same for
    //  "1" and "2." But "i" doesn't work.
    }
}

where "map" is an instance of google.maps.Map and each instance of popUps will differ in the final product.

I call this function when the page loads, which adds positions and markers to my map:

drawMap([[13.283 , 162.232], [18.232 , 112.223], [17.233, 80.293]]);

Does anyone know why I'm unable to create eventListeners dynamically? Any help would be greatly appreciated!

Thanks in advance. :)

Edit:

Turns out, the requirements here are only to have the divs pop up when the page loads. I didn't even need the event listener...

However, both answers were good and helped me figure out how to make the original code work, so thanks. :D

Upvotes: 3

Views: 3939

Answers (2)

Stephen O&#39;Connor
Stephen O&#39;Connor

Reputation: 1475

Create a function to add the maps listener, after your infowindow declaration. The function will create a closure and freeze the i value passed into it.

...
infowindow = new google.maps.InfoWindow({
        content: contents
    });

var addListener = function (i) {

google.maps.event.addListener(positions[i], 'click', function(){
        infoWindows[i].open(map, positions[i]);                 
    });
   ...

}

Then call it in your for loop:

addListener(i);

Upvotes: 6

hugomg
hugomg

Reputation: 69994

The inner function is closing over the variable i. At the end of the for-loop all the is will be points.length. This is a very common Javascript gotcha:

JavaScript closure inside loops – simple practical example

Upvotes: 1

Related Questions