-1

I have been trying to add info windows to Google Maps markers I am adding dynamically after receiving a JSON array from the server. My issue is, I believe, not understanding very well how Javascript handles variables and scope.

I tried this code:

$.getJSON("server", function(data) {
        if (data.items.length > 0) {
            var infowindow = new google.maps.InfoWindow({
              content: "placeholder"
            });
            for (var i = 0; i < data.items.length; i++) {
              var latLng = new google.maps.LatLng(data.items[i]["lat"],
                                                  data.items[i]["lng"]);
              var marker = new google.maps.Marker({
                position: latLng,
                map: map,
                title: data.items[i]["text"],
                icon: data.items[i]["alert_type"],
                animation: google.maps.Animation.DROP
              });
              marker.addListener('click', function() {
                infowindow.setContent(data.items[i]["text"]);
                infowindow.open(map, this);
              });
            } // end for
        } // end if
    }); // end getJSON

The problem with this code is that when I click a marker to display the infoWindow, I get an error saying data.items[i] is undefined but I know it is defined before I access it several times before that line of code (I removed code irrelevant to the question that accesses it too).

So, since I couldn't get access inside the function declaration, I created a var just before: var reportText = data.items[i]["text"]; and then inside the function changed the line with the problem to infowindow.setContent(reportText); which runs with no errors. However, when I click any marker, they all show the window with the same text, the text from the last report I received instead of being set to each one individually. I assume this is because the infowindow saves the variable location instead of the string value when it is set and therefore it reads the last value that was set to the variable.

Lastly, I tried to initialize my marker differently:

var marker = new google.maps.Marker({
  position: latLng,
  map: map,
  title: data.items[i]["text"],
  icon: data.items[i]["alert_type"],
  label: reportText,
  animation: google.maps.Animation.DROP
});

By setting the label to the text I want, I can do:

infowindow.setContent(this.label);

And I get the expected behavior on the infowindow of showing the correct text for each marker. My problem with this version is that I am using custom icons not designed for labels, and they look ugly with the character inside.

What I need is either a way to have the label property of a marker but not show the label in the marker, or, preferably, a way to make setContent copy the string value at the time instead of just saving a reference to the variable.

Any help is appreciated, thank you.

gamda
  • 580
  • 6
  • 24
  • 1
    possible duplicate of [Google Maps JS API v3 - Simple Multiple Marker Example](http://stackoverflow.com/questions/3059044/google-maps-js-api-v3-simple-multiple-marker-example) – geocodezip Jan 27 '16 at 20:10
  • possible duplicate of [Trying to display InfoWindow data from JSON on multiple markers](http://stackoverflow.com/questions/5137007/trying-to-display-infowindow-data-from-json-on-multiple-markers) – geocodezip Jan 27 '16 at 20:13
  • @geocodezip I had already seen this question (first comment) but dismissed it since in that case the array was local and I assumed it wouldn't be the same. However, now that I look closer I managed to adapt my code to work with that solution. Thank you – gamda Jan 27 '16 at 22:13

1 Answers1

0

After looking at the question in the first comment by @geocodezip and playing around with my own code I managed to get a working version. It involves making a global array which I'm not particularly happy about, but it has the expected behavior. Here is the working version of the code:

var texts = [];

function makeRequest() {
    $.getJSON("server/reports", function(data) {
        if (data.items.length > 0) {
            var infowindow = new google.maps.InfoWindow({
              content: "placeholder"
            });
            var text = "<ul>";
            for (var i = 0; i < data.items.length; i++) {
              var reportText = data.items[i]["text"];
              texts.push(reportText);
              text += "<li>"; 
              text += data.items[i]["text"] + "<br />";
              text += data.items[i]["end_date"];
              text += "</li>";
              var latLng = new google.maps.LatLng(data.items[i]["lat"],
                                                  data.items[i]["lng"]);
              var marker = new google.maps.Marker({
                position: latLng,
                map: map,
                title: data.items[i]["text"],
                icon: data.items[i]["alert_type"],
                animation: google.maps.Animation.DROP
              });
              google.maps.event.addListener(marker, 'click', (function(marker, i) {
                return function() {
                  infowindow.setContent(texts[i]);
                  infowindow.open(map, marker);
                }
              })(marker, i));
            } // end for
            text += "</ul>"
        } // end if
        document.getElementById("content").innerHTML = text;
    }); // end getJSON
}
gamda
  • 580
  • 6
  • 24