Anup Vasudeva
Anup Vasudeva

Reputation: 901

Filter's second parameter not working

I am trying to understand "filter" filter in AngularJS. Understanding from the docs, it also takes second parameter. If passed as "true", it performs a strict comparison.

The HTML

<fieldset>
    <legend>Array of objects (Search all properties)</legend>
    <input type="text" ng-model="searchObject" />
    <ul>
        <li ng-repeat="value in arrOfObjects | filter: searchObject: true">
            <span>{{value.firstName}}</span>
            <span> {{value.lastName}}</span>:
            <span><strong>{{value.email}}</strong></span>
        </li>
    </ul>
</fieldset>

THE JS

$scope.arrOfObjects = [
    {
        firstName: "Anup",
        lastName: "Vasudeva",
        email: "[email protected]"
    },
    {
        firstName: "Vijay",
        lastName: "Kumar",
        email: "[email protected]"
    },
    {
        firstName: "Virat",
        lastName: "Kohli",
        email: "[email protected]"
    }
];

What I am expecting, if I type "aNuP", it will try to make exact match with all the properties and would not be able to return anything. Hence I should be seeing an empty list.

Am I missing something.

Upvotes: 1

Views: 175

Answers (1)

Nathaniel Johnson
Nathaniel Johnson

Reputation: 4839

This is a plunker that shows the following explanation: http://plnkr.co/edit/b1vuJV4RFNQSdpfaw0Pd?p=preview

Angular filtering on objects works by comparing the object's fields to see if they contain the filter criteria while ignoring case. This gives a broad usage that can be narrowed by adding a second boolean parameter true to indicate that you want to drop the contains rule.

In your example:

<fieldset>
    <legend>Array of objects (Search all properties)</legend>

    <input type="text" ng-model="searchObject" />

    <ul>
        <li ng-repeat="value in arrOfObjects | filter: searchObject: true">
            <span>{{value.firstName}}</span><span> {{value.lastName}}</span>: <span><strong>{{value.email}}</strong></span>
        </li>
    </ul>
</fieldset>  

Typing Vasudeva, Anup or [email protected] will each filter out all but the first record because of an exact match on a single field. So an exact match on any field will result in the record being shown.

Removing the 'true':

<li ng-repeat="value in arrOfObjects | filter: searchObject">

Gives a much larger inclusion set because it looks for the expression in any field and ignores case so typing the letter a ,which appears in one or more fields all objects, lists all of the objects.

To filter on a single field in the object use this format:

<li ng-repeat="value in arrOfObjects | filter: {lastName :searchObject}">

and similarly you can add the second boolean parameter to get an exact match:

<li ng-repeat="value in arrOfObjects | filter: {lastName :searchObject}:true">

Finally you can create a custom filter by defining a function in your controller that returns true or false for a given match.

<li ng-repeat="value in arrOfObjects | filter: myEmailFilter">

And in your controller write the actual filter.

$scope.myEmailFilter = function(value) {
    console.log(value.email);
    if(value.email.indexOf("email.com")>=0) {
      console.log('true');
      return true;
    } else {
      console.log('false');
      return false;
    }
  };  

Upvotes: 2

Related Questions