0

I'm working on a map application, and I need to link different events to different types of markers. The createMarkers function creates a few markers by random, but their overlay events always say exactly the same though their colors are different. This is built on Leaflet.js

    function createMarkers() {
            for( var i = 0; i < 10; i++ ) {
                var color, kind;
                switch(Math.floor(Math.random() * 4)) {
                    case 0:
                        color = greenFlag;
                        kind = "film";
                    break;
                    case 1:
                        color = redFlag;
                        kind = "music";
                    break;
                    case 2:
                        color = blueFlag;
                        kind = "images";
                    break;
                    case 3:
                        color = yellowFlag;
                        kind = "text";
                    break;
                    default:
                }
                var lat = Math.random() * 3 - 75;
                var lng = Math.random() * 3 - 112;
                var marker = L.marker([lat, lng], {icon: color}).addTo(map).on('click', function() {
                    overlay(kind);
                });
            }
        }

    function overlay(kind) {
            alert(kind);
        }

All the markers created have the same value when clicked, e.g. "film". I've tried storing the overlay(kind) in a variable inside the first switch statement and calling that. I've also tried creating a second switch statement in the marker.on('click') function but neither of these has solved the problem. I feel like I'm missing something pretty key about javascript/objects here.

Thank you!

2
  • What is L ? is it (unintentionally) a global obect? Commented May 23, 2013 at 8:53
  • L is for the Leaflet.js object, its intentionally global. leafletjs.com Commented May 23, 2013 at 8:57

1 Answer 1

1

You need to create a closure so the scope of the outer function is retained.

function createMarkers() {

        for( var i = 0; i < 10; i++ ) {
            var color, kind;
            switch(Math.floor(Math.random() * 4)) {
                case 0:
                    color = greenFlag;
                    kind = "film";
                break;
                case 1:
                    color = redFlag;
                    kind = "music";
                break;
                case 2:
                    color = blueFlag;
                    kind = "images";
                break;
                case 3:
                    color = yellowFlag;
                    kind = "text";
                break;
                default:
            }
            var lat = Math.random() * 3 - 75;
            var lng = Math.random() * 3 - 112;
            var marker = L.marker([lat, lng], {icon: color}).addTo(map).on('click',overlay(kind));
        }
    }

function overlay(kind) {
  return function(){
        alert(kind);
  }
}
Sign up to request clarification or add additional context in comments.

5 Comments

Thank you! I've never really seen this concept before- it's really cool!
I think I understand why this works: by overlay() returning a function it encapsulates that function such that it won't be overwritten by the instantiation of newer markers. But I don't understand why/how new markers created in the for loop could know anything about their sibling instantiations, much less affect their onclick event. Maybe you could shed some light?
They didn't, they knew about i which after the loop was ran was set to 10.
This is the best explanation of closures I have found: jibbering.com/faq/notes/closures I read this about once a year, its a long read but well worth it.
haha, I stared at your response (which is very poetic at this time of night:) deciding whether to keep asking questions. thanks for coming back with this- i'm sure it will be an eye opener

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.