0

So google maps infowindow always displays the content of the last map item. Based on some research I stumbled accross this. However it still doesn't work for me here is my code.

 function bindInfoWindow(marker, map, infowindow, html) {
    marker.addListener('click', function () {
    infowindow.setContent(html);
    infowindow.open(map, this);
  });
 }

for (var x = 0; x < filtered_pins.length; x++) {
var links = filtered_pins[x].description + '<a href="' + filtered_pins[x].slug + '">read more..</a>';

links_arr.push(links);


    $.getJSON('http://maps.googleapis.com/maps/api/geocode/json?address=' + filtered_pins[x].city + '&sensor=false', null, function (data) {
        //console.log('4th'+ links);
        var p = data.results[0].geometry.location
        var latlng = new google.maps.LatLng(p.lat, p.lng);
        var marker = new google.maps.Marker({
            position: latlng,
            map: map,
        });
        var infowindow = new google.maps.InfoWindow();

        //marker.addListener('click', function () {
            //infoWindow.setContent(links);
        //    infowindow.open(map, this);
        //});

        bindInfoWindow(marker, map, infowindow, links);
        my_markers.push(marker);
    });
}

I have gone through quite a number of related items on Stackoverflow but they don't seem to be of service.They all seem to already have access to the latlang so their structure is different. I have to use the .getJson method to retrieve an addresses latlang first then create markers.

sqwale
  • 554
  • 3
  • 24

1 Answers1

1

Each iteration of your for loop calls $.getJSON(), however there is only a single links variable that every iteration shares. The for loop runs to completion before any of the $.getJSON() calls ever call your callback function. So all of them use the last value that was assigned into links.

It really is exactly the same problem as in the question you linked to; in the code in that question the problem variable is club. The reason the solution from that question didn't work is that your code has the $.getJSON() call which is asynchronous, just as the click handler is asynchronous.

To fix this, you can simply move the entire loop body into a function. The local variables inside that function will all be unique to each iteration of the loop.

The use of filtered_pins[x] seems OK here, but this could also be a problem if it were used inside the $.getJSON() callback, and it makes the code simpler to only have that at one point, where addMarker() is called.

And at this point you don't need bindInfoWindow() to be a separate function, so I moved it inline.

I also made a couple of other little changes to keep the line lengths shorter.

for (var i = 0; i < filtered_pins.length; i++) {
    addMarker( filtered_pins[i] );
}

function addMarker( pin ) {
    var links = pin.description +
        '<a href="' + pin.slug + '">read more..</a>';
    links_arr.push(links);

    var url = 'http://maps.googleapis.com/maps/api/geocode/json?address=' +
        pin.city + '&sensor=false';
    $.getJSON( url, null, function (data) {
        var p = data.results[0].geometry.location
        var latlng = new google.maps.LatLng(p.lat, p.lng);
        var marker = new google.maps.Marker({
            position: latlng,
            map: map,
        });
        var infowindow = new google.maps.InfoWindow();

        marker.addListener('click', function () {
            infowindow.setContent(links);
            infowindow.open(map, this);
        });

        my_markers.push(marker);
    });
}

I'm not sure what the links_arr and my_markers arrays are used for, so there could be some problems there as well, depending.

In modern browsers, you could also fix this by using let instead of var for your variables inside the loop. Then you wouldn't need the addMarkers() function. But I think this separate function makes the code cleaner, and it's still compatible with old browsers.

Michael Geary
  • 28,450
  • 9
  • 65
  • 75
  • Brilliant thank you it worked. Not sure why this works and moving the contents of the function into my forloop does not. – sqwale Jun 20 '17 at 12:36