Can someone give me an example of how to use Angular filter comparator?
From official doc:
function(actual, expected): The function will be given the object value and the predicate value to compare and should return true if the item should be included in filtered result.
There is a great blog post talking about Angular filter:
Fun with AngularJS filters - Part 1: the filter
filter
However, at the end of it, where I am looking for some useful example of the function comparator, I still found nothing.
For more particular matching needs, you can pass a function instead of a boolean as the comparator argument.
I have tried few combinations by myself. Neither adding the function at the end of the expression or pointing to a function in scope do the work.
DETAILED EXPLANATION ON HOW filter : expression : comparator
works.
This is the filter syntax:
data | filter: expression : comparator
The AngularJS built-in filter
function provides a non-case sensitive substring search on the data it is passed, comparing against the expression
when the expression is a string or a property of an object subject to the filter. The comparator
gives you the ability to further refine the filter. If you simply specify the comparator
as true
, it will ensure that only items which are an exact match to the expression
are returned. A more flexible approach is to specify the comparator
as a function which returns a predicate function.
EXAMPLES
With the following data exposed in a view's $scope
as people:
var people = [
{name:'John Jones',location:'Peterborough'},
{name:'Angela Atkinson',location:'Jersey'},
{name:'Peter Peterjon',location:'Attleborough'}
];
We'll set up a simple input search box on the view, which we'll give as the filter expression parameter:
<input type="text" ng-model="searchText" placeholder="Search People">
1) WITHOUT COMPARATOR
The results of the search will be output where we invoke the filter:
<p ng-repeat="person in people | filter : searchText">{{person.name}} {{person.location}}</p>
If we type 'J' into the search box, because all entries have a j somewhere, the result will still show all 3 entries.
Demo: https://plnkr.co/edit/VID2CAKvUI5mjgKLImaI?p=preview
2) WITH COMPARATOR AS true
<p ng-repeat="person in people | filter : searchText : true">{{person.name}} {{person.location}}</p>
Typing 'J' will show no results as there is no field which is exactly J. We'll only get a result if any of the following are typed in (case sensitive):
Demo: https://plnkr.co/edit/hhw2u03egXsUo7IyGc1w?p=preview
3) WITH COMPARATOR AS function
We'll attach a custom comparator predicate function called customComparator
to the $scope
of the controller. I set it up to require a full match but it's no longer case sensitive. We use it as follows:
<p ng-repeat="person in people | filter : searchText : customComparator">{{person.name}} {{person.location}}</p>
Demo: https://plnkr.co/edit/Iy9r9bLQQdzefuzUv0TD?p=preview
4) CUSTOM FILTER
Instead of using the built in filter
with expression and comparator we can just create a custom filter and pipe |
into that. Such a custom filter which does exactly the same as WITH COMPARATOR AS function
above might look like this:
.filter('customFilter',[function() {
var customFilter = function(arr,searchText){
if(! searchText)
return arr;
return arr.filter(function(arrayItem){
var match = false;
for(var key in arrayItem) {
if(! arrayItem.hasOwnProperty(key) || key === '$$hashKey')
continue;
if(arrayItem[key].toLowerCase() === searchText.toLowerCase()) {
match = true;
break;
}
}
return match;
});
};
return customFilter;
}])
and it would be used as follows:
<p ng-repeat="person in people | customFilter : searchText">{{person.name}} from {{person.location}}</p>
Note that this syntax is not expression : comparator
. Instead, it is customFilter : filterArgument
.
Demo: https://plnkr.co/edit/wWT3cjfy7867WUSqqSKj?p=preview
I did something like this, since Angular iterates on objects and tries to compare them whole as well as recursively their individual properties.
// in your controller
$scope.filterMyData = function (input, search_param) {
if (input && input.propertyWeCareAbout) {
// it's ugly, but to quickly get something done you can ignore search_param
return input.propertyWeCareAbout === $scope.SomeOtherData;
}
else {
return angular.equals(input, search_param);
}
}
<span>Quick search: </span><input type="search" ng-model='quickSearch'/><br/>
<table>
<tr ng-repeat="obj in someHttpService.dataAsArray | filter:quickSearch:filterMyData">
<td>{{ obj.key }} </td>
<td>{{ obj.propertyWeCareAbout }}</td>
</tr>
</table>
In my case, "quickSearch" is largely meaningless, and filtering was done by a different logic. You can always just chain another filter at the end by adding "| filter:quickSearch" into ng-repeat.
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