Angular function filter comparator example

23,057

Solution 1

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.

Solution 2

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):

  • John Jones
  • Peterborough
  • Angela Atkinson
  • Jersey
  • Peter Peterjon
  • Attleborough

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

Share:
23,057

Related videos on Youtube

bigbearzhu
Author by

bigbearzhu

Updated on July 09, 2022

Comments

  • bigbearzhu
    bigbearzhu almost 2 years

    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.