Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 6 of 6
  1. #1
    New to the CF scene
    Join Date
    Sep 2011
    Posts
    1
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Event listeners won't use correct objects

    I feel like I must be missing something simple but I can't put my finger on it...

    I'm moderately new to JS (programmed in other languages though) and am working on a Google Maps project.

    This piece of code should show an alert of the region's name when a map polygon is clicked. Instead, no matter what polygon is clicked, it only does the name for the LAST iterated placemark.

    Code:
    for (var i = 0; i < placemarks.length; i++) {
    	placemark = placemarks[i]
    	google.maps.event.addListener(placemark.polygon, "click", function() {
    		alert(placemark.name);
    	});
    }
    What am I misisng? What would be a better way of handling this?

  • #2
    Regular Coder
    Join Date
    Sep 2011
    Location
    Sweden
    Posts
    154
    Thanks
    1
    Thanked 22 Times in 22 Posts
    Classic problem. Has to do with JavaScript closures - or actually lack thereof.
    The function assigned to the event handler will remember placemark:s last value in placemark:s scope (which is unclear to me from your code snippet - is it perhaps even global?) - which means placemarks:s value when you've finished your for loop. This is not good since all events will have the same value for placemark.

    Solve it like this:
    Code:
    for (var i = 0; i < placemarks.length; i++) {
      (function(){
         var placemark = placemarks[i]
         google.maps.event.addListener(placemark.polygon, "click", function() {
           alert(placemark.name);
         });
      })();
    }

  • #3
    Senior Coder xelawho's Avatar
    Join Date
    Nov 2010
    Posts
    2,980
    Thanks
    56
    Thanked 557 Times in 554 Posts
    or like this (which is really the same thing):

    Code:
    for (var i = 0; i < placemarks.length; i++) {
    	placemark = placemarks[i];
            addlistener (placemark);
           }
    
    function addlistener (placemark){
    google.maps.event.addListener(placemark.polygon, "click", function() {
    		alert(placemark.name);
    	});
    }

  • #4
    Senior Coder Dormilich's Avatar
    Join Date
    Jan 2010
    Location
    Behind the Wall
    Posts
    3,335
    Thanks
    13
    Thanked 348 Times in 344 Posts
    Quote Originally Posted by ironboy View Post
    Has to do with JavaScript closures - or actually lack thereof.
    I disagree (about the lacking part). JavaScript has Closures and the observed behaviour is according to its definition, since the value of a variable in a Closure is determined on execution time (when the event occurs), not on definition time (inside the loop).
    The computer is always right. The computer is always right. The computer is always right. Take it from someone who has programmed for over ten years: not once has the computational mechanism of the machine malfunctioned.
    André Behrens, NY Times Software Developer

  • #5
    Regular Coder
    Join Date
    Sep 2011
    Location
    Sweden
    Posts
    154
    Thanks
    1
    Thanked 22 Times in 22 Posts
    Sorry, for being unclear:
    Javascript has/is built on closures. The code presented was lacking them.

  • #6
    Kor
    Kor is offline
    Red Devil Mod Kor's Avatar
    Join Date
    Apr 2003
    Location
    Bucharest, ROMANIA
    Posts
    8,478
    Thanks
    58
    Thanked 379 Times in 375 Posts
    There is also, a no less elegant solution, to use the closure, but to create custom properties for the objects within the loop:

    Code:
    for (var i = 0; i < placemarks.length; i++) {
    placemark = placemarks[i];
    placemark.polygon.pname=placemark.name;
    google.maps.event.addListener(placemark.polygon, "click", function() {
    alert(this.pname);
    });
    }
    KOR
    Offshore programming
    -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*


  •  

    Tags for this Thread

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •