Custom Filters in AngularJS
In Angular, filters give us a nice way to format the data we use in our apps, or present to the user. Angular provides a subset of filters out of the box, or we can write our own. In this post we’ll do just that.
Creation
To create a filter, we simply attach it to our module, name it, and return the data input.
Note: It is best practice to create a module for your filters, aside from your main module.
angular.module('myApp')
.filter('slug', function () {
return function (input) {
if (input) {
return input;
}
};
});
Ok, so the above filter is getting our data argument, and returning it, but not doing anything. Let’s give it some actual filtering to do. We’ll setup our filter to normalize the data passed to it, by forcing it to lowercase, and replacing any spaces with underscores.
angular.module('myApp')
.filter('slug', function () {
return function (input) {
if (input) {
return input.toLowerCase().replace(/[^a-z_]/g, '_');
}
};
});
Invoking
Now that we’ve got this sweet filter, let’s use it. Angular gives us the option of invoking filters in either HTML or JS. We’ll go over both.
First, HTML. We call our filter inside an expression using the pipe character inside the {{ }} syntax. This allows us to pipe our date into our expression as an argument.
{{ 'Rob Stinogle' | slug }}
// Displays: rob_stinogle
Second, Javascript. We can invoke our filter by injecting the $filter dependency into our controller. We then have access to both Angular’s and our filters, including our custom slug filter. We can pass both our filter name and data as arguments.
angular.module('myApp')
.controller('myCtrl', function ($scope, $filter) {
var userName = 'Rob Stinogle';
$scope.userSlug = $filter('slug')(userName);
console.log($scope.userSlug);
});
// Displays: rob_stinogle
And that’s it! As usual, Angular makes things crazy simple and organized. Let me know if you have any questions!
Comments (18)
Leave a Reply
Nice simple and useful, I was not very clear on how to use it inside of Javascript from the documentation but this drives it straight home. It reminds me of Handlebars helpers that I appreciate so much. Thanks again for the quick tip.
Link to commentThanks Ady! I’m hoping to provide more Angular tips in the near future… I’m loving the library. You should try it on the next AE project…
Link to commentWill do. I write a lot of mini apps with angular whenever I can and am looking for the excuse to integrate it in the AE codebase. Keep up the good stuff 🙂
Link to commentGreat article Rob. I was reading angular docs about filter and got really confused about syntax. According to docs limitTo has the following syntax.
Link to comment{{ limitTo_expression | limitTo : input : limit}}
However, I’ve never seen input parameter passed to limitTo like this. I always do something like limitTo: 5, for example (without input, I wonder why) Can you please explain that. Thanks. Can you provide some example that uses {{ limitTo_expression | limitTo : input : limit}} syntax. Thanks
Hey Rob,
Can you tell me the advantage of declaring your module each time you create a new controller/filter/etc? I.E. angular.module(‘myApp’).controller, angular.module(‘myApp’).filter, etc.
I’ve seen this used instead of:
var app = angular.module(‘myApp’);
Link to commentapp.controller({});
app.filter({})
Hey Mike,
I’ve seen both used before. There may be a small speed improvement from using variables (there usually is), but I prefer to see the module structure in each controller/etc. Just personal preference.
Link to commentLoved how you kept it simple. I am not a programmer but my sweetie is. He needs help with angularJS filter filters. He is able to do a custom filter, however, when he makes a list – I mean, pipes a chain of custom filters, only one filter will work. How can one have multiple custom filters, that work simultaneously ?
Link to commentYou can chain filters together like this:
Link to comment{{ expression | filter1 | filter2 | ... }}
Thank you. I appreciate your quick response. The problem arose when he had multiple filters, and some custom filters in the chain). It would not support multiple list, for example: {{expression1 | filter1 | custom filter | filter 2 | filter3
Link to comment{{expression2 | filter1 | filter2 | custom filter | filter2
. . . and so on with multiple list. At the time only one line (expression) would work at a time, but not simultaneously. the good thing is, he solved it this morning. Thanks again, Rob.
It turns out that chaining them was fine. The issue was that the filter itself needed to check to see if data was there first and would not start processing until there was something to filter on. The solution was to update the filter. P.S. I am not a programmer by any means, and not in a techie field at all. So, I hope I have been clear enough to help someone else. Love your website. Makes me want to learn basic coding 🙂
Link to commentI’m completely new to Angular and have this question with the syntax. Why do we have nested functions as part of filter definition. Why can’t be it like this?
Link to comment.filter(‘slug’, function (input) {
if (input) {
return input.toLowerCase().replace(/[^a-z_]/g, ‘_’);
}
});
Just what I was looking for.
Learning Angular is a bit painful. I looked in several places but they all recycled the same examples.
But you have got insight on the subject and can explain it.
Thanks.
Link to commentThank you so much! I couldn’t find the answer on stackoverflow but then came across this post.
Link to commentHey Rob,
Link to commentCan we enable and disable filter from controller?
If you want to use your filter inside a controller, you’ll need to inject it first. Check the Angular doc on filters for more info on usage inside a controller.
Link to commentThanks a lot I couldn’t find a simple answer anywhere but then came across your post.
Link to commentThere is something called jsfiddle to show demo. just saying
Link to commentThank you! This was a big time saver!
Link to comment