Given a controller with a $scope property that is an object with other properties rather than an array like below, how should I filter the ng-repeat
set?
Here is a JSFiddle: http://jsfiddle.net/ZfGx4/110/
Controller:
function HelloCntl($scope, $filter) { $scope.friends = { john: { name: 'John', phone: '555-1276' }, mary: { name: 'Mary', phone: '800-BIG-MARY' }, mike: { name: 'Mike', phone: '555-4321' }, adam: { name: 'Adam', phone: '555-5678' }, julie: { name: 'Julie', phone: '555-8765' } }; }
Template:
<div ng:app> <div ng-controller="HelloCntl"> <input placeholder="Type to filter" ng-model="query"> <ul> <li ng-repeat="(id, friend) in friends | filter:query"> <span>{{friend.name}} @ {{friend.phone}}</span> </li> </ul> </div> </div>
The performance is way better (1.63x faster) when we use built-in map function or slightly better/worse when we use built-in filter/reduce.
Using JavaScript `map()` and `filter()` Together for Composition. JavaScript's Array#map() and Array#filter() functions are great when used together because they allow you to compose simple functions.
The “filter” Filter in AngularJS is used to filter the array and object elements and return the filtered items. In other words, this filter selects a subset (a smaller array containing elements that meet the filter criteria) of an array from the original array.
I would change my data structure to an array. Anyway, here's another implementation to filter your friends object.
angular.module('filters',['utils']) .filter('friendFilter', function(utils){ return function(input, query){ if(!query) return input; var result = []; angular.forEach(input, function(friend){ if(utils.compareStr(friend.name, query) || utils.compareStr(friend.phone, query)) result.push(friend); }); return result; }; });
This iterates over the object only once, compares by name
and phone
and can be called like this.
<li ng-repeat="friend in friends | friendFilter:query">
I defined the compareStr
in another module, but you don't really need to do it.
angular.module('utils', []) .factory('utils', function(){ return{ compareStr: function(stra, strb){ stra = ("" + stra).toLowerCase(); strb = ("" + strb).toLowerCase(); return stra.indexOf(strb) !== -1; } }; });
Don't forget to inject the filters
module into your app
angular.module('app',['filters'])
Here's the full example: http://jsbin.com/acagag/5/edit
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With