3 min read

This article written by, Jim Lavin, author of the book AngularJS Services will cover ways on how to transform data. Sometimes, you need to return a subset of your data for a directive or controller, or you need to translate your data into another format for use by an external service. This can be handled in several different ways; you can use AngularJS filters or you could use an external library such as underscore or lodash.

(For more resources related to this topic, see here.)

How often you need to do such transformations will help you decide on which route you take. If you are going to transform data just a few times, it isn’t necessary to add another library to your application; however, if you are going to do it often, using a library such as underscore or lodash will be a big help.

We are going to limit our discussion to using AngularJS filters to handle transforming our data. Filters are an often-overlooked component in the AngularJS arsenal. Often, developers will end up writing a lot of methods in a controller or service to filter an array of objects that are iterated over in an ngRepeat directive, when a simple filter could have easily been written and applied to the ngRepeat directive and removed the excess code from the service or controller.

First, let’s look at creating a filter that will reduce your data based on a property on the object, which is one of the simplest filters to create. This filter is designed to be used as an option to the ngRepeat directive to limit the number of items displayed by the directive.

The following fermentableType filter expects an array of fermentable objects as the input parameter and a type value to filter as the arg parameter. If the fermentable’s type value matches the arg parameter passed into the filter, it is pushed onto the resultant array, which will in turn cause the object to be included in the set provided to the ngRepeat directive.

angular.module(‘brew-everywhere’)
.filter(‘fermentableType’, function () {
return function (input, arg) {
var result = [];
angular.forEach(input, function(item){
if(item.type === arg){
result.push(item);
}
})
return result;
};
});

To use the filter, you include it in your partial in an ngRepeat directive as follows:

<table class=”table table-bordered”>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Potential</th>
<th>SRM</th>
<th>Amount</th>
<th>&nbsp;</th>
</tr>
</thead>
<tbody>
<tr ng-repeat=”fermentable in fermentables |
fermentableType:’Grain'”>
<td class=”col-xs-4″>{{fermentable.name}}</td>
<td class=”col-xs-2″>{{fermentable.type}}</td>
<td class=”col-xs-2″>{{fermentable.potential}}</td>
<td class=”col-xs-2″>{{fermentable.color}}</td>
</tr>
</tbody>
</table>

The result of calling fermentableType with the value, Grain is only going to display those fermentable objects that have a type property with a value of Grain.

Using filters to reduce an array of objects can be as simple or complex as you like. The next filter we are going to look at is one that uses an object to reduce the fermentable object array based on properties in the passed-in object.

The following filterFermentable filter expects an array of fermentable objects as an input and an object that defines the various properties and their required values that are needed to return a matching object. To build the resulting array of objects, you walk through each object and compare each property with those of the object passed in as the arg parameter. If all the properties match, the object is added to the array and it is returned.

angular.module(‘brew-everywhere’)
.filter(‘filterFermentable’, function () {
return function (input, arg) {
var result = [];
angular.forEach(input, function (item) {
var add = true
for (var key in arg) {
if (item.hasOwnProperty(key)) {
if (item[key] !== arg[key]) {
add = false;
}
}
}
if (add) {
result.push(item);
}
});
return result;
};
});

LEAVE A REPLY

Please enter your comment!
Please enter your name here