AO_
AO_

Reputation: 2894

Trying to get a variable into an addListener function which is run inside a loop

I'm trying to get a variable into an addListener function which is run inside a loop, but it always only takes notice of the last instance of the loop variable.

e.g.

for(var i=0; i < data.length; i++) {
    points[i] = new google.maps.LatLng(parseFloat(data[i].lat), parseFloat(data[i].lng));
    gmarkers[i] = new google.maps.Marker({
        map: map,
        position: points[i],
        title: locationdata[i].title
    });
    gmarkers[i].setMap(map);
    bubbles[i] = new google.maps.InfoWindow({
        content: locationdata[i].summary
    });
    google.maps.event.addListener(gmarkers[i], 'click', function() {
        alert(i);
        bubbles[i].open(map, gmarkers[i]);
    });
}

So the problem is that near the bottom the alert(i) is always the data.length's last item, which makes sense, but I don't know how to correct this.


Rocket answered this question and was correct, but the syntax was slightly off, so posting here what the real syntax was for anyone that comes across this later on:

google.maps.event.addListener(gmarkers[i], 'click', (function(i) {
    return function() {
        alert(i);
        bubbles[i].open(map, gmarkers[i]);
    }})
(i));

Upvotes: 0

Views: 186

Answers (3)

Kasper Vesth
Kasper Vesth

Reputation: 4113

Another way to do this is to put your addListener function in another function, and call that in the loop. As Rocket said in his answer it is a question of closures which can be a huge issue if you don't understand it. I am not saying that I do, but I have tried a couple of things and I like it better when you use a seperate method like so:

function addEventListener(i){
    google.maps.event.addListener(gmarkers[i], 'click', function() {
        alert(i);
        bubbles[i].open(map, gmarkers[i]);
    });
}

But it is just a matter of personal preference. Just thought I'd throw in the other option as well :)

Upvotes: 0

BishopZ
BishopZ

Reputation: 6378

Yet another question that Frame.js was designed to solve. Here is a more readable and scalable solution using Frame:

for(var i=0; i < data.length; i++) {
    Frame(function(next, i){
        google.maps.event.addListener(gmarkers[i], 'click', function() {
            alert(i);
        });
        next();
    }, i);
}
Frame.init();

Upvotes: 0

gen_Eric
gen_Eric

Reputation: 227310

This is a classic issue in JavaScript. You need to make a closure for each of the listeners.

google.maps.event.addListener(gmarkers[i], 'click', (function(i) {
    return function(){
        alert(i);
        bubbles[i].open(map, gmarkers[i]);
    };
})(i));

Upvotes: 1

Related Questions