[GIS] Leaflet controls are not appearing with Promise function

jqueryleaflet

I am not receiving any errors in the console either.
I am attempting to use the Promise function instead of callback.

var map;
var centerlatlng = L.latLng(38, -98);
var aDiv;
var geojsonfeatures;

$(document).ready(function() {

  var aLayerOne = L.tileLayer('http://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png', {
    attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>, Tiles courtesy of <a href="http://hot.openstreetmap.org/" target="_blank">Humanitarian OpenStreetMap Team</a>'
  });

  var aLayerTwo = L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
    attribution: 'Tiles &copy; Esri &mdash; Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'
  });

  var aLayerThree = L.tileLayer('http://{s}.tile.openweathermap.org/map/precipitation_cls/{z}/{x}/{y}.png', {
    attribution: 'Map data &copy; <a href="http://openweathermap.org">OpenWeatherMap</a>',
    opacity: 0.5
  });

  var aLayerFour = L.tileLayer('http://{s}.tile.openweathermap.org/map/temp/{z}/{x}/{y}.png', {
    attribution: 'Map data &copy; <a href="http://openweathermap.org">OpenWeatherMap</a>',
    opacity: 0.5
  });


  var aLayerFive = L.tileLayer('http://{s}.tile.openweathermap.org/map/pressure_cntr/{z}/{x}/{y}.png', {
    attribution: 'Map data &copy; <a href="http://openweathermap.org">OpenWeatherMap</a>',
    opacity: 0.5
  });

  var points = L.geoJson(geojsonfeatures, {
    filter: function(feature, layer) {
      return feature.properties.COUNTRY != "UNITED STATES";
    },
    pointToLayer: function(feature, latLng) {
        return L.marker(latLng)
          .bindPopup(feature.properties.NAME);
      } // end of function
  });

  map = L.map('myMap', {
    center: centerlatlng,
    zoom: 4,
    layers: [aLayerOne]
  });

  var promise = $.getJSON("js/weatherstations.js");
  promise.then(function(geojsonfeatures) {
    var weatherstations = L.geoJson(geojsonfeatures);
    points.addTo(map)
    // Add a Layers Control
    var baseMaps = {
      "Open Street Map HOT": aLayerOne,
      "Esri Imagery": aLayerTwo
    };

    var overLays = {
      "Precipitation": aLayerThree,
      "Temperature": aLayerFour,
      "Barometric Pressure": aLayerFive,
      "California Weather Stations": weatherstations
    };

    L.control.layers(baseMaps, overLays).addTo(map);

    // Add a Scale Control
    L.control.scale().addTo(map);

    // Add a Full Screen Control
    // use  "new" in its construct
    new L.Control.FullScreen().addTo(map);

    // Add a Locate Control
    // images folder must be within the same folder as L.Control.Locate.css file
    L.control.locate().addTo(map);

    ///Creating custom control here
    // part 1/3 : Creates a control with the given position
    var aControl = L.control({
      position: 'bottomright'
    });

    // part 2/3 : Should contain code that creates all the neccessary DOM elements for the control
    aControl.onAdd = function() {
      aDiv = L.DomUtil.create('div', 'aCustomC'); // create a div with a class "aCustomC"
      aDiv.innerHTML = "Open-Source Weather Map"; // Each HTML element has an innerHTML property that defines both the HTML code and the text that occurs between that element's opening and closing tag.
      return aDiv;
    }; // end function onAdd

    // part 3/3 : Add the control to the map
    aControl.addTo(map);
    ////////
    var searchControl = new L.esri.Controls.Geosearch().addTo(map);
    var results = new L.LayerGroup().addTo(map);
    searchControl.on('results', function(data) {
      results.clearLayers();
      for (var i = data.results.length - 1; i >= 0; i--) {
        results.addLayer(L.marker(data.results[i].latlng));
      }
    });

    $('.aToolTip').tooltip({
      'container': 'body'
    }); // this works

    $('.aPopOver').popover({
      'container': 'body'
    }); // this works

  });

});

Best Answer

Your syntax for the promise is correct (example below) but there are a few other possible issues.

  • You're trying to use geojsonfeatures before your geojson is available when you create the variable named points.
  • Pass an error handler to your promise's then method to catch errors from the call to getJSON (example below).
  • Verify your geojson is valid by using a callback-based version of your code or plug your geojson into geojson.io.

By slightly tweaking my example from a previous answer, here's an example of using .then() as opposed to a callback passed $getJSON():

<html>
<head>
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" />
</head>
<body>
    <div id="map" style="width: 600px; height: 400px"></div>

    <script src="http://code.jquery.com/jquery-2.1.0.min.js"></script>
    <script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
    <script>
    var map = L.map('map').setView([29.7628, -95.3831], 10);

    L.tileLayer('https://{s}.tiles.mapbox.com/v3/{id}/{z}/{x}/{y}.png', {
        maxZoom: 18,
        attribution: 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' +
            '<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
            'Imagery © <a href="http://mapbox.com">Mapbox</a>',
        id: 'examples.map-i875mjb7'
    }).addTo(map);

    var gj = $.getJSON('https://rawgit.com/boehnert/GeoJson/master/coolPlaces.geojson');
    gj.then(
        function(response) {
            console.log('promise success handler', response);
            var geojsonLayer = new L.GeoJSON(response);
            geojsonLayer.addTo(map);    
        },
        function(error) {
            console.log('promise error handler', error);
        }
    );
    </script>
</body>
</html>