Reputation: 1424
In my project i try to synchronize filters with geojson displayed in table and on map. To achieve this i used angular and previously angular-leaflet-directive, but performance was to slow for my purposes so i decide to make my own directive for leaflet.js.
In my case i can pass data from controller to my directive, but it makes map static, when i try to pass data after filtering in order to make my map dynamic, map is not showing any markers and i get Error from leaflet, Invalid Geojson Object.
Here Fiddler with my example: http://jsfiddle.net/ior88/5ea8yxwo/4/
$scope.FilteredGeojson = function () {
var result;
result = $filter('filter')($scope.data, $scope.search);
$scope.geojson = result;
return result;
};
If you will look into console there you will see error.
I don't get it because when i display geojson or geojson_watch in {{}} it looks the same as geojson in data, So assume the problem here is filtering? I will be really thankful to somebody who will tell me where i make errors
Upvotes: 2
Views: 1481
Reputation: 28638
First off, what you are showing is not a GeoJSON object. That Leaflet's L.GeoJSON
accepts just an array of features, doesn't make it a valid GeoJSON object, so you shouldn't call it a GeoJSON object. It's an array of GeoJSON feature objects. In a valid GeoJSON featurecollection object the feature array is contained like this:
{
"type": "FeatureCollection",
"features": [
// The features
]
}
Next, you're trying to filter some complex objects in a way that doesn't work. Here is how $filter('filter')
works:
var simpleArray = [{
'name': 'Foo'
}, {
'name': 'Bar'
}];
$filter('filter')(simpleArray, {'name': 'Foo'}); // Returns array with Foo object
$filter('filter')(simpleArray, {'name': 'Bar'}); // Returns array with Bar object
$filter('filter')(simpleArray, {'name': 'Foobar'}); // Returns empty array
Example on Plunker: http://plnkr.co/edit/I7OGfoJLwaCz0XibcTDB?p=preview
What you are trying to do with $filter('filter')
:
var complexArray = [{
'properties': {
'name': 'Foo'
}
}, {
'properties': {
'name': 'Bar'
}
}];
$filter('filter')(complexArray, {'name': 'Foo'}); // Returns empty array
$filter('filter')(complexArray, {'name': 'Bar'}); // Returns empty array
$filter('filter')(complexArray, {'name': 'Foobar'}); //Returns empty array
Example on Plunker: http://plnkr.co/edit/rUtseKWCeyLiewDxnDDn?p=preview
Why? Because the objects in the array do not have a property called name
. They only have a property called properties
, that contains an object and that does have a name
property. You can't expect the filter to recursivily go searching through your object untill it finds a name property. It doesn't. It only does when you explictly tell it to do so:
$filter('filter')(complexArray, {'properties': {'name': 'Foo'}}); // Returns with Foo
$filter('filter')(complexArray, {'properties': {'name': 'Bar'}}); // Returns with Bar
$filter('filter')(complexArray, {'properties': {'name': 'Foobar'}}); // Returns empty
Example on Plunker: http://plnkr.co/edit/LpOvr7Zxw5C5A3Tt5umQ?p=preview
So you'll need to setup your logic a bit different, say you want to search for two properties, id
and name
In your scope you would have:
$scope.search = {
'properties': {}
};
$scope.$watch('search', function (newVal, oldVal) {
if (newVal !== oldVal) {
$scope.data = $filter('filter')($scope.source, $scope.search);
}
}, true);
And in your template:
<input ng-model="search.properties.id" placeholder="ID" />
<input ng-model="search.properties.name" placeholder="Name" />
Now everytime you use one of the inputs, the watch on the search property gets fired, which filters the source and updates the data. To reflect that change in your directive also, you've also got to put a watch on the data object in the link
method of your directive. In there you can update the layer with the new data:
scope.$watch('data', function (newVal, oldVal) {
if (newVal !== oldVal) {
geojsonLayer.clearLayers();
geojsonLayer.addData(scope.data);
}
}, true);
Entire code in a working example on Plunker: http://plnkr.co/edit/CmfBdmt7BYKPmE22HLvl?p=preview
Upvotes: 3