Q:

How to use angular filter on multiple properties of the object

I have a simple ng-repeat like that:
<input type="text" ng-model="vm.filter">

<div ng-repeat="tenant in vm.tenants | filter : vm.filter : vm.contains">
 </div>

Now I want to filter tenants based on the value of the filter, e.g. to find if a name of a tenant contains the filter expression like that
function contains(actual, expected) {
            return actual.name.indexOf(expected) >= 0;
        }

What I do not understand is why I get a tenant.name in the contains function instead of the tenant itself.  I know for a simple case I can do something like filter | {name: vm.filter} | vm.contains, but what if I want to do filtering based on multiple properties (e.g. name, phone, etc.) 

A:

What I do not understand is why I get a tenant.name in the contains
  function instead of the tenant itself. 

What's happening is that angular is providing the comparator all levels of the object in an attempt to do a deep filtering i.e. it attempts to match your filter to all hierarchy levels in the object.  If you console.log all the values, you'll see that you get the full object too (after all the properties). 

One way to make this work would be something like
...
<div ng-repeat="tenant in vm.tenants | filter : vm.contains(vm.filter)">
...

and then
...
contains: function(filter) {
  return function(tenant) {
    return tenant.name.indexOf(filter) ! == -1;
  }
}
...

Fiddle - https://jsfiddle.net/81384sd7/

