How to chain AngularJS filters in controller How to chain AngularJS filters in controller angularjs angularjs

How to chain AngularJS filters in controller


You can just re-filter what you get returned from your first filter. So on and so forth.

var filtered;filtered = $filter('filter')($scope.list, {name: $scope.filterParams.nameSearch});filtered = $filter('orderBy')(filtered, $scope.filterParams.order);

Below plunkr demonstrates the above.

http://plnkr.co/edit/Ej1O36aOrHoNdTMxH2vH?p=preview


In addition to explicitly applying filters to the result of the previous one you could also build an object that will chain multiple filters together.

Controller

angular.module('Demo', []);angular.module('Demo')    .controller('DemoCtrl', function($scope, $filter) {        $scope.order = 'calories';        $scope.filteredFruits = $scope.fruits = [{ name: 'Apple', calories: 80 }, { name: 'Grapes', calories: 100 }, { name: 'Lemon', calories: 25 }, { name: 'Lime', calories: 20 }, { name: 'Peach', calories: 85 }, { name: 'Orange',    calories: 75 }, { name: 'Strawberry', calories: 65 }];        $scope.filterFruits = function(){            var chain = new filterChain($scope.fruits);            $scope.filteredFruits = chain                .applyFilter('filter', [{ name: $scope.filter }])                .applyFilter('orderBy', [ $scope.order ])                .value;        };        function filterChain(value) {            this.value = value;        }        filterChain.prototype.applyFilter = function(filterName, args) {            args.unshift(this.value);            this.value = $filter(filterName).apply(undefined, args)            return this;        };    });

View

<!doctype html><html ng-app="Demo">  <head>    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.js"></script>    <script src="script.js"></script>    <link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">  </head>  <body><div ng-controller="DemoCtrl">  <input type="text" ng-model="filter" ng-change="filterFruits()" placeholder="Filter Fruits" />  <select ng-model="order">    <option value="name">name</option>    <option value="calories">calories</option>  </select>  <div ng-repeat="fruit in filteredFruits">    <strong>Name:</strong> {{fruit.name}}    <strong>Calories:</strong> {{fruit.calories}}  </div></div>  </body></html>


This is a typical case for FP libraries like lodash or Ramda. Make sure your common data is applied as last arg to each filter. (in this case columns)

$scope.columnDefs = _.compose(    $filter('filter3'),    $filter('filter2'),    $filter('filter1'))($scope.columns)

or with extra args

$scope.columnDefs = _.compose(    $filter('filter3').bind(null, optionalArg1, optionalArg2),    $filter('filter2').bind(null, optionalArg1),    $filter('filter1'))($scope.columns)