12

My project uses a JSON feed to grab info about earthquakes within a specified latitude and longitude boundary, essentially making a box. I take this info and turn all the results into markers on a Google map. I need each marker to also display some additional information, so I'm trying to use the built in InfoWindow objects such that when you click on a marker you open up the tooltip with some information associated with that marker. However I'm finding that no matter what marker I click, the same infowindow always comes up above the same marker of that group, and I believe it is always the last infowindow created in my loop. Here's the code.

$.getJSON(url, function(json) {
                    for(var i = 0; i < json.earthquakes.length; i++)
                    {
                        var pos = new google.maps.LatLng(json.earthquakes[i].lat, json.earthquakes[i].lng);
                        var info = json.earthquakes[i].lat + ", " + json.earthquakes[i].lng;
                        var marker = new google.maps.Marker({
                            map: map, 
                            position: pos,
                            title: json.earthquakes[i].eqid
                        })
                        var tooltip = new google.maps.InfoWindow({
                            content: info
                        })
                        google.maps.event.addListener(marker, 'click', function() {
                            tooltip.open(map, marker);
                        });
                        markers.push(marker);
                        tooltips.push(tooltip);
                    }               
                });

markers is an array for all the marker objects on the map and tooltips is another array for storing the infowindows objects. They're global.

Kara
  • 6,115
  • 16
  • 50
  • 57
Mathias Schnell
  • 884
  • 3
  • 13
  • 22
  • This is due to how closures work (marker is passed by reference to the closure, what you would want is a copy). But when the listener is called, it will be with `this` referring to the object (marker) to which the listener was added, so you can just use `this` instead of `marker`. – herman Jul 30 '14 at 12:34

3 Answers3

20

This is a very common question in the google-maps tag and an easy mistake to make :).

What is happening is that your click event is being called asynchronously and it is picking up the current value in the marker variable in the getJSON callback (the last one in the list).

You need to wrap your addListener call in a function so that a closure is created around the marker variable that is being used in the click callback:

function listenMarker (marker)
{
    // so marker is associated with the closure created for the listenMarker function call
    google.maps.event.addListener(marker, 'click', function() {
                        tooltip.open(map, marker);
                    });
}

Then call listenMarker from your main getJSON callback (where you are currently calling addListener).

Community
  • 1
  • 1
RedBlueThing
  • 42,006
  • 17
  • 96
  • 122
  • 3
    Thank you for this simple and clear solution. Using infowindow, you can just pass a few more parameters into the function to add more content. – dwarbi Aug 05 '11 at 03:30
  • -1: although this works, it's not necessary as `this` will refer to the object that the listener is added to. – herman Jul 30 '14 at 12:32
4

YOu can also do this:

// so marker is associated with the closure created for the listenMarker function call
google.maps.event.addListener(marker, 'click', function() {
                    tooltip.open(map, this);
                });

Where "marker" is replace with "this" in the add listener call. Thus you can place the addListerner code at the same point you create the marker, and not have to create a new function.

http://you.arenot.me/2010/06/29/google-maps-api-v3-0-multiple-markers-multiple-infowindows/

Check out the full solution and a demo :D

Colin Wiseman
  • 848
  • 6
  • 10
2

Placing the addListener call into its own function also solves the problem of multiple infowindows all displaying the same text.

notreadbyhumans
  • 607
  • 9
  • 17