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