Building Multiple Filters with Lo-Dash and AngularJS

Thursday, May 29, 2014

You can try the code in this post yourself.

Imagine we have the following movie data returned by an API call from the server.

var movies = [
    { title: "Godzilla", genre:"Action", released: 2014},
    { title: "Neighbors", genre: "Comedy", released: 2014},
    { title: "Into The Woods", genre: "Musical", released: 2014},
    . . .
];

Now, we need to display the data and allow the user to filter on genre, release year, or both. First, we’ll use lodash to build a unique list of available options for these attributes, and then store the options in scope.

app.controller("mainController", function($scope, movieData) {

    $scope.movies = movieData.getAll();

    $scope.genres = _.chain($scope.movies).pluck("genre").uniq().sortBy().value();
    $scope.years = _.chain($scope.movies).pluck("released").uniq().sortBy().value();

    $scope.clearFilters = function(){
        $scope.selectedGenre =  undefined;
        $scope.selectedYear = undefined;
    };

});

In the view we can build the filtering selects and a table using ngOptions and ngRepeat.

<div ng-controller="mainController">

  <select ng-model="selectedGenre" ng-options="genre for genre in genres"></select>
  <select ng-model="selectedYear" ng-options="year for year in years"></select>
  <button ng-click="clearFilters()">Clear</button>

  <table class="table">
    <thead>. . . </thead>
    <tbody>
      <tr ng-repeat="movie in movies |
            filter:{ genre: selectedGenre, released:selectedYear }">
        <td>{{movie.title}}</td>
        <td>{{movie.genre}}</td>
        <td>{{movie.released}}</td>
      </tr>
    </tbody>
  </table>

</div>

Notice how the filter filter in Angular understands how to take an object expression and apply predicates to the specified attributes.


Comments
gravatar Linn Tindemann Friday, May 30, 2014
Hey Scotty boy. I think you are working against the framework in your mainController. Thanks, Love; Linny Tin
gravatar Daniel Mackay Saturday, May 31, 2014
Hi Scott, Couldn't you achieve the same thing using the filter: "filter:search" and two inputs with ng-model="search.genre" and ng-model="search.years"? Similar to the example in the documentation: https://docs.angularjs.org/api/ng/filter/filter Cheers, Dan
gravatar john Saturday, May 31, 2014
realistically, people want to be able to check off multiple years and genres. would love to see this achieved with filter filter. Thanks
gravatar Klaudiu Wednesday, June 4, 2014
Same with john. Would love to see a filter with multiselect.
Comments are now closed.
by K. Scott Allen K.Scott Allen
My Pluralsight Courses
The Podcast!