tobias47n9e February 2016

How to prevent overriding an event listener

I want to create a map using Google Maps API, and connect a number of markers to individual event listeners.

My JS file looks like this (abbreviated):

var MainObject = (function($) {

    return {
        init: function() {
            this.set_up_map(); 
    },

    set_up_map: function() {
        //...
        var map = new google.maps.Map(map_div, map_props);

        function add_click_events(row_id) {
            $(row_id).addClass('highlight');
        }

        function draw_rows(rows) {
            for (var i = 0; i < rows.length; i++) {
                var row = rows[i];
                var row_latlng = new google.maps.LatLng(
                    row.lat,
                    row.long);
                var marker = new google.maps.Marker(
                    {
                        position: row_latlng,
                        map: map,
                    });

                google.maps.event.addListener(marker,
                    "click",
                    function() {add_click_events(row);}
                );
            }
        }
        // call data
        draw_rows(rows);
        }
    })(jQuery);

I would like to have it iterate over the markers and connect each to its callback (having an individual row_id that should get highlighted). But with the structure above I overwrite all the event listeners with the last (so only the last row is highlighted no matter which marker is clicked).

What is a good way of debugging or even solving this?

Answers


BenG February 2016

you need to use a closure:-

(function(i) {
  var row = rows[i];
  var row_latlng = new google.maps.LatLng(
    row.lat,
    row.long);
  var marker = new google.maps.Marker({
    position: row_latlng,
    map: map,
  });
  google.maps.event.addListener(marker,
    "click",
    function() {
      add_click_events(row);
    }
  );
})(i);


Viktor Kukurba February 2016

You should use function closure for that.

function draw_rows(rows) {
        for (var i = 0; i < rows.length; i++) {
            (function(row){
              var row_latlng = new google.maps.LatLng(
                row.lat,
                row.long);
                var marker = new google.maps.Marker(
                  {
                    position: row_latlng,
                    map: map,
                  });

                google.maps.event.addListener(marker,
                  "click",
                  function() {add_click_events(row);}
                );
            })(rows[i]);
        }
    }

Also you can use let, but it is supported only in newest browsers

let row = rows[i];

Post Status

Asked in February 2016
Viewed 3,466 times
Voted 13
Answered 2 times

Search




Leave an answer