For those who don’t know, Angular comes with some pretty powerful filters baked right into the system. They are great for transforming values in a view to look the way we want. They can also be used to weed out values we don’t want to show. In addition to this, you can also use these filters in your views to create new variables that can then be used in other places in your views. At InfoTrust, we recently used this functionality to keep our objects and controller logic more organized.
To demonstrate this, let’s build a quick application that will separate out great drummers that are still alive with those who have passed on to the “Great Drum Set in the Sky.” The code for this post can be found here. You can find a demo of the finished product here. Let’s start by setting up our basic skeleton application. Create a new directory and put the following in a file called index.html in that directory.
<!DOCTYPE html>
<html lang="en" ng-app="filterTest">
<head>
<meta charset="UTF-8">
<title>Angular Filters</title>
<style>
[ng:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
display: none !important;
}
#drummer-lists, form {
float: left;
}
#drummer-lists {
width: 40%;
}
form {
width: 50%;
}
</style>
</head>
<body ng-cloak>
<div ng-controller="fooController">
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script>
(function(angular) {
var app = angular.module('filterTest', []);
app.controller('fooController', ['$scope',
function($scope) {
console.log('hello');
}
]);
})(angular);
</script>
</body>
</html>
If you run this file in a web browser and open up the developer console, you should see “hello” printed to the screen. This means everything is hooked up correctly. All we have done here is create the basic HTML markup for our application. Then we include AngularJS on the page and then create our Angular application and add a controller to it. Let’s initialize our controller with some data and add a method to our scope that will add a new drummer to the list. Put the following inside the controller function.
$scope.newDrummer = {};
$scope.drummers = [
{ firstName: 'Neil', lastName: 'Peart', alive: true },
{ firstName: 'John', lastName: 'Bonham', alive: false },
{ firstName: 'Keith', lastName: 'Moon', alive: false },
{ firstName: 'Buddy', lastName: 'Rich', alive: false },
{ firstName: 'Dave', lastName: 'Grohl', alive: true },
{ firstName: 'Ringo', lastName: 'Star', alive: true },
{ firstName: 'Mike', lastName: 'Portnoy', alive: true },
{ firstName: 'Lars', lastName: 'Ulrich', alive: true },
{ firstName: 'Stewart', lastName: 'Copeland', alive: true },
{ firstName: 'Travis', lastName: 'Barker', alive: true },
{ firstName: 'Chad', lastName: 'Smith', alive: true },
{ firstName: 'James', lastName: 'Sullivan', alive: false },
{ firstName: 'Tony', lastName: 'Williams', alive: false },
{ firstName: 'Luke', lastName: 'Holland', alive: true },
{ firstName: 'Matt', lastName: 'Greiner', alive: true },
];
$scope.addDrummer = function() {
$scope.newDrummer.alive = $scope.newDrummer.alive === 'true';
$scope.drummers.push($scope.newDrummer);
$scope.newDrummer = {};
};
This code is pretty simple. We are creating an object called “newDrummer” that we will populate using our form later. We then create an array of drummer, each with a first name, last name, and whether they are alive or not. Lastly, we create a function that will be run when our form is submitted that will add the drummer to the array and then clear it out. The first line of the function simply compares the “alive” value to the string “true” and puts that boolean value in alive. This is because our filter will look for the boolean true, but a select list will initially put the string “true” in our object. This simply turns the string “true” or “false” into their boolean counterparts.
Now that we have our data, let’s get some of this showing in the browser. Put the following in the template for the controller.
{% raw %}
<div id="drummer-lists">
<ul>
<li ng-repeat="drummer in drummers | filter: { alive: true }">
</li>
</ul>
<ul>
<li ng-repeat="drummer in drummers | filter: { alive: false }">
</li>
</ul>
</div>
{% endraw %}
This creates two unordered lists, one with all the drummers who are still alive and the other with those who are not. We are easily able to filter them out using the “filter” filter. The object we pass it shows what must be true in each object for it to be included in the output ng-repeat puts in our list.
Let’s add a form to the page so we can add a drummer to our list. Put the following after our drummer lists.
<form ng-submit="addDrummer()">
<h1>Add a drummer</h1>
<label for="firstName">First Name</label>
<input name="firstName" type="text" ng-model="newDrummer.firstName">
<label for="lastName">Last Name</label>
<input name="lastName" type="text" ng-model="newDrummer.lastName">
<label for="alive">Is Alive?</label>
<select name="alive" ng-model="newDrummer.alive">
<option value="">Pick an option</option>
<option value="no">False</option>
<option value="yes">True</option>
</select>
<input type="submit" value="Add Drummer">
</form>
This is a simple form that will populate the fields in our newDrummer object on our $scope and then will fire our “addDrummer” function once the form has been submitted. You will now be able to fill out the form, submit it, and see your drummer added to one of the lists.
Now, let’s say we wanted to add a counter to each of our lists. We could manage all that in our controller by reducing our array to numbers to count the number of each type of drummer in our list, but that would be alot more code than is necessary. Instead, we can manage this all in our views. Change the lists to look like the following code.
{% raw %}
<div id="drummer-lists">
<p>Number of awesome drummers still alive: / </p>
<ul>
<li ng-repeat="drummer in alive = (drummers | filter: { alive: true })">
</li>
</ul>
<p>Number of awesome drummers that have passed on: / </p>
<ul>
<li ng-repeat="drummer in dead = (drummers | filter: { alive: false })">
</li>
</ul>
</div>
{% endraw %}
This is very similar to before. However, notice we have instead used the filter on the drummers array and then saved that value in new array called “alive” and “dead.” It still iterates through this object like before. We can also use this object elsewhere in our view. I have chosen to add a counter to show how many are in each list. This is much nicer than handling it in the controller because it will automatically update when we add, change, or remove something in the drummers array.
Filters in Angular can be very powerful. When used correctly, they can help keep the logic in your application organized and keep you controllers from being too big. Make sure to leave us comment below to let us know how this has helped you!