Strae
Strae

Reputation: 19465

Variables overriden into a for loop

I'm trying to add markers to a Google maps using V3. I have my places into an json object (places):

var num_places = places.length;
for(var i = 0; i < num_places; i++)
{
    place_lat_lng = new google.maps.LatLng(places[i].lat, places[i].lng);
    var infowindow = new google.maps.InfoWindow({
        content: '<h2>' + places[i].name + '</h2><p>' + places[i].body + '</p>'
    });
    var marker = new google.maps.Marker({
        position: place_lat_lng,
        map: mymap,
        title: places[i].name,
        zIndex: i
    });
    google.maps.event.addListener(marker, 'click', function() {
        infowindow.open(mymap, marker);
    });
}

The code insert the markers, but when I click on any of them the infoWindow show (and move the map) always to the last marker in the list.

I tryed to use an array to for the infoWindow:

var infoWindow = new Array();
for(var i = 0; i < num_places; i++)
{
    [...]
    var infowindow[i] = new google.maps.InfoWindow({
        content: '<h2>' + places[i].name + '</h2><p>' + places[i].body + '</p>'
    });
    [...]
    google.maps.event.addListener(marker, 'click', function() {
        infowindow[i].open(mymap, marker);
    });
}

But nothings change.

Where am I mistaking?

Upvotes: 4

Views: 142

Answers (2)

Matti Virkkunen
Matti Virkkunen

Reputation: 65176

In JavaScript, only functions create a new scope/closure. Therefore you only ever have one infowindow variable, which is captured into the inner function, but which in the end will point to the last window. Use a self-calling function to set up a new closuse:

for (var i = 0; ...) {
    (function() {
        var infowindow = ...;
    })();
}

Note that the value of i will still not be captured separately. Currently you don't seem to need it, but if you do, pass it to the function to create a local version of it inside the function:

(function(i) { // this is the new local i with the value passed in from the outside
    // ...accessible here
})(i); // this is the outer i

Upvotes: 2

Alan Geleynse
Alan Geleynse

Reputation: 25149

Change this:

google.maps.event.addListener(marker, 'click', function() {
        infowindow.open(mymap, marker);
    });

to:

google.maps.event.addListener(marker, 'click', function(infowindow) {
        function() {
            infowindow.open(mymap, marker);
        });
    }(infowindow);

The problem is that your infowindow variable is getting recreated in the loop each time, and when the click handler fires, it is looking in a local closure for the most recent version. The updated code creates a new closure that will contain the version of infowindow that is unique to that iteration of the loop.

Upvotes: 0

Related Questions