I am having issues getting Leaflet's layer control to work if using GeoJSON files stored online, on Amazon Web Services. The points from the online file do show up with their popups as expected, but the actual layer control window at the top right of the map that allows you to select/deselect layers isn't there anymore. This is the JS part of the code that I am trying to run, with one of the links/GeoJSON files as an example:

function addDataToMap(data, map) {
    var dataLayer = L.geoJson(data, {
    pointToLayer: function (feature, latlng) {
    return L.circleMarker(latlng, point_style); 
    onEachFeature: function(feature, layer) {
        var popupText = 'Name  --  ' + feature.properties.NAME + '<br>' + 'Address  --  ' + feature.properties.ADDRESS;
                 layer.bindPopup(popupText); }
     $.getJSON("https://s3.amazonaws.com/aws-website-homebuyerrecommendationsystemfordenver-ag706/lightrail_geojson.json", function(data) { addDataToMap(data, map); }); 

var baseLayers = {
    "Light Rail Stations": dataLayer,
    "Parks": parks_popup
L.control.layers(null, baseLayers, {collapsed:false}).addTo(map);

If I pull the GeoJSON files as variables within the code then my layer control works fine. But I have several layers that I need to add and they are quite large, so hosting them online and pulling them with a simple $.getJSON command would be useful. Otherwise my html file becomes very long and freezes often while scrolling around.

Any ideas as to what I'm doing wrong? Or is the only way to get the layer control functionality from Leaflet to store the GeoJSONs as local variables?

1 Answer 1


I believe your problem is that JQuery's getJSON function is asynchronous.

addDataToMap is called, starts the request for the JSON data, but doesn't wait for a reply. It continues to process the JS file, preparing your baselayers and finally adding the control to the map. Only problem is that it didn't wait for the reply and is essentially trying to add a undefined or Promise to the map, essentially no map. The reply is returned after the map control was set, so the map features load but not the controls.

It works in your one-file model because the JS Engine parses everything before executing. The data is already there.

Either do a pure AJAX synchronous call, from a UX standpoint is less than ideal or in your anonymous callback add addOverlay to update your controls.

Here is a working example using your dataset. I annotated the code with reasoning and comments. Take a look, I structured it slightly differently too, IMO for better maintenance and scaling. Of course there are other ways to do this but the process will be the same.


Note: You may have change the view to full page, the control seems to hide if the window is too small.

  • @ RomaH I tried using: $.ajax({ dataType: "json", async: false, url: "s3.amazonaws.com/…", data: data, success: function () { L.geoJson(data).addTo(map); } }); but it didn't work. I also tried adding the addOverlay statement in my layer control line but nothing. Is there any other way to import the geojson with ajax, or am I doing it wrong?
    – spartmar
    Aug 17, 2016 at 22:23
  • @spartmar I provided a working example and updated my answer. It works for me, take a look.
    – RomaH
    Aug 18, 2016 at 0:07
  • so now the layer control works with other layers and that's great. But the ability to show customized styles on the other layer I just added is gone. I also can't seem to get the popups to show. Window says "undefined" but the feature.properties I am showing are correct. Ideas? Oh and thanks for all your help so far!
    – spartmar
    Aug 18, 2016 at 1:40
  • I didn't fully implement the L.geoJson call that you used in your code, I only load the points and style them; I was just showing how to load the points. If you look at line 18 through 31, you will not see an onEachFeature, you will need to add that. For styling, you will need to create new styles like on line 18 and then add that createPointOverlay call, similar to line 44.
    – RomaH
    Aug 18, 2016 at 14:35
  • Yes, I had replicated the same example and added styling and popups to other layers with no luck. However I just realized that the function was exactly the same and so that's where the issue was. Can't use the same exact parameters for points as for polygons or lines. But I fixed the newer polygon layers so they're called by an updated function... All is working as expected now! Thank you for all your help! :)
    – spartmar
    Aug 18, 2016 at 20:07

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.