Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filtering on object map rather than array in AngularJS

Tags:

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> 
like image 983
mbrevoort Avatar asked Dec 14 '12 23:12

mbrevoort


People also ask

Which is faster map or filter?

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.

Can we use map with filter?

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.

How does filter work in AngularJS?

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.


1 Answers

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

like image 124
jaime Avatar answered Sep 22 '22 17:09

jaime