1

So I have this code, that loops through every town in window.towns, which is a nested object sorted by the first character of the town name. Like so:

//sample data:
window.towns = { 
    'A' : { 
        "Aberdeen" : { 
            "town_info": {
                 "google_maps": {
                     "lat" : 47.561236,
                     "lng" : 0.1235467 }
                         }
                     } , 
        "Agency Village" : {
            "town_info": {
                 "google_maps": {
                     "lat" : 47.561236,
                     "lng" : 0.1235467 }
                         }
                     } 
           },
    'B' : { //towns beginning with B
          },
    'C' : {},
 // ... all the way thru 'Z'
}

My code then loops through each letter of the alphabet, and for each letter, loops through the towns that start with that letter, creates a marker on the google map for each town, and an info window that appears when you click on the marker.

for (var alphabet in window.towns) {
    for (var town in window.towns[alphabet]) {

        var info = window.towns[alphabet][town].town_info;

        if (info !== undefined &&
            typeof info !== undefined &&
            info.google_maps !== undefined &&
            typeof info.google_maps !== undefined) {

            var lat = info.google_maps.lat,
                lng = info.google_maps.lng;

            info.marker =
                new window.google.maps.Marker({
                    position: new window.google.maps.LatLng(lat,lng),
                    map: map,
                    title: window.towns[alphabet][town].post_title,
                    icon: icon_image
                });

            info.marker.iwindow =
                new window.google.maps.InfoWindow({
                    content: '<strong><a href="#'+
                        window.towns[alphabet][town].post_title
                            .replace(' ','-','g').toLowerCase()+
                        '" class="town">'+
                        window.towns[alphabet][town].post_title+
                        '</a></strong>'
                });

            window.google.maps.event.addListener(info.marker, 'click', function() {
                this.iwindow.open(map,this);
            });
        }
    }
}

The code works fine as is. However, I get a JSLint error, "don't make functions within a loop", which makes sense. How do I convert my code to avoid making a function within the loop, when the anonymous function depends on the value of this being equal to the current info.marker?

clov3rly
  • 70
  • 5

1 Answers1

2

You can define a small function before the loop and then just refer to that local function from within the loop:

Before the loop:

function handleMarkerClick() {
    this.iwindow.open(map,this);
}

Then, in the loop:

for (var alphabet in window.towns) {
    for (var town in window.towns[alphabet]) {

    // ....

    window.google.maps.event.addListener(info.marker, 'click', handleMarkerClick);
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • This works... but now I get 'Possible strict violation', due to having `this` within the function. Is it worth doing anything about? Yes :) – clov3rly Jan 28 '14 at 22:12
  • @CloverLeaf - there is no actual violation because `addListener()` sets `this` appropriately when it's call. Not sure why jsLint is objecting - I guess it just isn't sure you know what you're doing even though you actually do. [This question](http://stackoverflow.com/questions/16553264/why-is-jshint-throwing-a-possible-strict-violation-on-this-line) about jsHint contains an answer for how to work around the warning with a special comment - not sure if the same method works for jsLint or not. – jfriend00 Jan 28 '14 at 22:19