views:

61

answers:

1

My code is below, and I had an issue with nearly the same code, and it was fixed here on StackOverflow, but, again, its not working. I haven't changed the working code, but i did wrap it in the for...in loop youll see below. The issue is that no matter what marker I click it always triggers the last marker/infoWindow that was placed.

$(function(){
    var latlng = new google.maps.LatLng(45.522015,-122.683811);
    var settings = {
        zoom: 10,
        center: latlng,
        disableDefaultUI:true,
        mapTypeId: google.maps.MapTypeId.SATELLITE
    };
    var map = new google.maps.Map(document.getElementById("map_canvas"), settings);
    $.getJSON('api',function(json){
        for (var property in json) {
            if (json.hasOwnProperty(property)) {
                var json_data = json[property];
                var the_marker = new google.maps.Marker({
                    title:json_data.item.headline,
                    map:map,
                    clickable:true,
                    position:new google.maps.LatLng(
                        parseFloat(json_data.item.geoarray[0].latitude),
                        parseFloat(json_data.item.geoarray[0].longitude)
                    )
                });
                var infowindow = new google.maps.InfoWindow({
                    content: '<div><h1>'+json_data.item.headline+'</h1><p>'+json_data.item.full_content+'</p></div>'
                });
                new google.maps.event.addListener(the_marker, 'click', function() {
                    infowindow.open(map,the_marker);
                });
            }
        }
    });
});

Thank you for whoever figures this out!

+1  A: 

What's going on is that when you create each of your event handler closures (functions):

new google.maps.event.addListener(the_marker, 'click', function() {
    infowindow.open(map,the_marker);
});

...they each get an enduring reference to the variable the_marker, not its value at the moment the closure is created. So all copies of that closure function use the same value (the last value assigned to it in the loop). Closures are not complicated (more here), but let's just say you're not the first person to make this mistake. :-) It's very easy to do.

So what you want to do is capture the value of the_marker as of that loop iteration, which is easily done:

new google.maps.event.addListener(
    the_marker,
    'click',
    buildHandler(map, the_marker));

function buildHandler(map, marker) {
    return function() {
        infowindow.open(map, marker);
    };
}

There, we have a function that builds the handler using the arguments passed into the function, and we call that function on each loop iteration to create our handler for us.

This answer to another question on SO may help you visualize how closures get access to variables.

T.J. Crowder
Sweet! works, well, i got another issue, but i think I can figure it out from this... the same content (see the infowindow var) shows up in each one. So, im trying to create a function to capture the value for that too. Thanks again!
Oscar Godson
Nice, actually, added var infowindow to the buildHandler function, works like a charm, Thanks so much!
Oscar Godson
@Oscar: Doh! I missed that that varied on each loop as well. But hey, call it the "left as an exercise for the reader" part. ;-)
T.J. Crowder