Search code examples
javascriptangularjsleafletgeojsonangular-leaflet-directive

Integrating AngularJS + Leaflet


I'm building a webapp using AngularJS and Leaflet. I've tried angular-leaflet-directive but it makes the webapp too slow and unresponsive (I have +2000 points and many complex polygons).

I use $http.get to load a GeoJSON of polygons into Leaflet, and bind the same data into Angular. The properties of the GeoJSON features populate a table, and I filter the table by the polygons ID (also a feature.property), like so:

<div ng-repeat="bcd in nycd.features | filter: {properties.borocd: last_clicked} ">
    <div>{{ bcd.properties.borocd }}</div>
</div>

An this is the Angular app:

var mapApp = {}; //container for the leaflet layers

var app = angular.module('app', []);
app.controller('mainController', function($scope, $http) {

  $http.get('linkToData.json')
  .success(function(data) {
    $scope.last_clicked = 101; //default ID to begin

    $scope.nycd = data;
    mapApp.nycd = L.geoJson($scope.nycd, {
      onEachFeature: function (feature, layer) {
        layer.on('click', function(e) {
          $scope.last_clicked = feature.properties.borocd; //change ID with map click
        });
      },
      style: style
    });
    mapApp.nycd.addTo(map);
  })
  .error(function(data) {
    console.log('Error: ' + data);
  });
});

However, when I click the map my $scope.last_clicked variable is updated, but the filter for the ng-repeat is not. I've tested filtering the ng-repeat with <input type="number" ng-model="last_clicked"> and it works, but still nothing while clicking on the Leaflet map. Any ideas why?


Solution

  • The solution is to use $scope.$apply(), as pointed out by charlietfl in the comments.

    Updating the code in the original question:

    ...
        mapApp.nycd = L.geoJson($scope.nycd, {
          onEachFeature: function (feature, layer) {
            layer.on('click', function(e) {
              $scope.last_clicked = feature.properties.borocd; //change ID with map click
              $scope.$apply(); //this updates the filter
            });
    ...
    

    Not sure I fully understand why it was not updating automatically before, but maybe this article can help.