Pipe vs Filter in Angular JS

I like doing web-apps and love to evaluate the latest features with new frameworks. As I was going through the Angular 2 new features and was trying to compare it with the previous features of the 1.x. I discovered that a pipe is used for piping and not for filters anymore… by the way there are no more filters… wow… convenient. Isn’t it? So, here is the blog to share my findings on differences between pipes and filters. Most of the examples available on web with pipes are in typescript and so I thought its worth exploring the area with ES6. So, here we have all the examples in ES6. Cheers!!!

What is a Pipe?

  • Pipe (fluid conveyance), a hollow cylinder following certain dimension rules
  • Anonymous pipe and named pipe, a one-way communication channel used for inter-process communication
  • Vertical bar, sometimes called pipe , the ASCII character |
  • You can connect two commands together so that the output from one program becomes the input to the next program. Two or more commands connected in this way form a pipe.

Yes, we are talking about last one from above. In computer programming, especially in UNIX operating systems, a pipe is a technique for passing information from one program process to another. Unlike other forms of Interprocess Communication (IPC), a pipe is only a one-way communication. Basically, a pipe passes a parameter such as the output of one process (program1) to another process (program2) which accepts it as input. The system temporarily holds the piped information until it is read by the receiving process. The grep command in UNIX shows best use of pipe to filter data.

The grep Command in UNIX

The simplest use of grep is to look for a pattern consisting of a single word. It can be used in a pipe so that only those lines of the input files containing a given string are sent to the standard output. If you don’t give grep a filename to read, it reads its standard input; that’s the way all filter programs work. Here we used grep command for matching patterns, let us see how to use filter for more than this.

About Filter

Now, we know what is Pipe and how it works in UNIX. The Pipe was formerly known as filters in AngularJS 1.x. In Angular 1, we had filter which helped format, sort or transform how data was displayed in our templates. Filters can be used with a binding expression or a directive. In Angular 2, we have a similar feature but renamed to Pipes. This rename was to better align of what the feature does. Coming from the Unix background we | pipe together commands. So in Angular we use the same | pipe character to format our data.

Angular 2 has many new concepts and some of the same concepts from Angular 1.x. Most of the filters from Angular 1.x are retained in Angular 2.0 pipes, in addition to the creation of newer pipes. Angular 1.x and Angular 2 have an equal number of filters to pipes, but there isn’t a direct crossover.

The following table shows a comparison:

Filter/Pipe Name Angular 1.x (Filter) Angular 2 (Pipe)
currency
date
uppercase
json
limitTo
lowercase
number
orderBy
filter
async
decimal
percent
slice
replace
I18nSelect
I18nPlural

Formatting Data with Filters

Filters allow you to declare how to transform data for display to the user within an interpolation in your template. The syntax for using filters is:

Where, expression is any Angular expression, filterName is the name of the filter you want to use, and the parameters to the filter are separated by colons. The parameters themselves can be any valid Angular expression.

Following is an example of currency filter :

We add this declaration in the view (rather than in the controller or model) because the dollar sign in front of the number is only important to humans, and not to the logic we use to process the number.

Filters can also be chained with additional pipe symbols in the binding. For example, we can format the previous example for no digits after the decimal by adding the number filter, which takes the number of decimals to round to as a parameter. So:

Sorting Data with Filters

The orderBy filter allows us to sort an array. By default, strings are sorted alphabetically, and numbers are sorted numerically. The syntax for using orderBy filter is:

The expression used to determine the order. The expression can be of type String or Function or Array. The array items can be both strings and functions. The reverse is optional. To sort in ascending order, set reverse to false. To sort in descending order, set reverse to true. You can also use + and to sort in ascending and descending order respectively.

Following is an example of orderBy filter :

Custom Filters

You’re not limited to the bundled filters, and it is simple to write your own. If we wanted to create a filter that title-cased strings for our headings, for example, we could do so as follows:

With a template like this:

and inserting the pageHeading as a model variable via a controller:

we would see something resembling like following.

Behold! -The Majesty Of Your Page Title

Source code of Angular 1.X filters is available here.

Why pipes?

AngularJS 1.x has a filter called filter , which allows us to do sort, format and transform. However, the duplication of the names often leads to confusion. That’s another reason the core team renamed the filter component to pipe . Pipes don’t give you any new feature. In angular 2 you can use logics in templates too. You also can execute a function in the template to get its returned value. But pipes is a beautiful way to handle these things in templates. It makes your code more clean and structured.

Angular 2 comes with several pipes, like following,

  • CurrencyPipe: This pipe is used for formatting currency data. As an argument, it accepts the abbreviation of the currency type (that is, “EUR”, “USD”, and so on).
  • DatePipe: This pipe is used for the transformation of dates.
  • DecimalPipe: This pipe is used for transformation of decimal numbers. The argument it accepts is of the following form: “{minIntegerDigits}.{minFractionDigits}-{maxFractionDigits}”.
  • JsonPipe: This transforms a JavaScript object into a JSON string.
  • LowerCasePipe: This transforms a string to lowercase.
  • UpperCasePipe: This transforms a string to uppercase.
  • PercentPipe: This transforms a number into a percentage.
  • SlicePipe: This returns a slice of an array. The pipe accepts the start and the end indexes of the slice.
  • AsyncPipe: This is a stateful pipe that accepts an observable or a promise.

Formatting Data with Pipes

The responsibility for formatting data in AngularJS 1.x was assigned to filters. Another example for a data formatting requirement is when we use collections of items. For instance, if we have a list of items, we may want to filter it based on a predicate (a boolean function); in a list of numbers, we may want to display only prime numbers, Pipe or Filter is hero here.

The motivation behind the new name is the syntax used for pipes and filters:

In the preceding example, we apply the pipes, decimal and currency, to the value returned by expression. The entire expression between the curly braces looks like Unix pipe syntax.

Lets look at a simple pipe built into Angular 2 the date pipe. The date pipe simply formats our date in our templates.

The date Wed May 3 2016 22:01:58 GMT-0600 (Central Standard Time) would be formatted to 5/3/2016 and May 3, 2016.

Customizing your Pipe

The syntax for defining pipes is similar to the one used for the definition of directives and components. In order to create a new pipe, all we need to do is to provide a name for the pipe and define the data formatting logic. During runtime, once the Angular 2 expression interpreter finds out that a given expression includes a call of a pipe, it will retrieve it out of the pipes collection allocated within the component and invoke it with the appropriate arguments.

The following example illustrates how we can define a simple pipe called lowercase1 , which transforms the given string, passed as argument to its lowercase representation:

Now let’s demonstrate how we can use the lowercase1 pipe inside a component:

We can use the App component with the following markup:

Source code of Angular 2 pipes is available here.

Stateful and Stateless Pipes

There are two categories of pipes, stateless and stateful. Stateless pipes are pure and Stateful pipes are impure. Before going ahead with stateless and stateful, Let us go through pure and impure.

Pure and Impure Pipes

There are two categories of pipes: pure and impure. Pipes are pure by default. Every pipe we’ve seen so far has been pure. We make a pipe impure by setting its pure flag to false. By setting pure property in pipe, we can declare whether we want the pipe it implements the logic for to be either stateful or stateless.

Here is the syntax for pure property :

The pure property is important, because in case the pipe is pure, the change detection can be optimized. Angular looks for changes to data-bound values through a change detection process that runs after every JavaScript event: every keystroke, mouse move, timer tick, and server response. This could be expensive in terms of execution time and performance. When a pipe is used, Angular strives to lower the cost whenever possible and appropriate. Angular picks a simpler, faster change detection algorithm.

Pure pipes :

Angular executes a pure pipe only when it detects a pure change to the input value. A pure change is either a change to a primitive input value (String, Number, Boolean, Symbol) or a changed object reference (Date, Array, Function, Object). Angular ignores changes within (composite) objects and doesn’t call a pure pipe – for example, when an input month is changed, adding to an input array, or updating an input object property. This may seem restrictive but is also fast. An object reference check is fast — much faster than a deep check for differences — so Angular can quickly determine if it can skip both the pipe execution and a view update. For this reason, we prefer a pure pipe if we can live with the change detection strategy. When we can’t, we may turn to the impure pipe.

Impure pipes :

Angular executes an impure pipe during each and every component’s change detection cycle. An impure pipe will be called frequently, as often as every keystroke or a mouse-move. An impure pipe must be implemented carefully.  It may be an expensive, long-running pipe could destroy the user experience.

Stateless pipe

Stateless pipes are pure types that flow input data through without remembering anything or causing detectable side-effects. Most pipes are stateless. There was one common property between all the pipes mentioned earlier—all of them return exactly the same result each time we apply them to the same value and pass them the same set of arguments. Such pipes that hold the referentially transparency property are called pure pipes. The DatePipe we used and the LowercasePipe1 pipe we created both are examples of a stateless pipe.

Source code of stateless pipe’s example is available here.

Stateful pipe

Stateful pipes are those which can manage the state of the data they transform. A pipe that creates an HTTP request, stores the response and displays the output, is a stateful pipe. Stateful Pipes should be used cautiously, as we know it is impure pipe.

The Angular AsyncPipe is an interesting example of an impure pipe as well as stateful. The AsyncPipe accepts a Promise or Observable as input and subscribes to the input automatically, eventually returning the emitted value(s). The AsyncPipe maintains a subscription to the input and its returned values depend on that subscription.

Source code of stateful pipe’s example is available here.

Pipe vs filter

Angular 1.X had a concept of filters. Pipes are very much similar to that but it has some significant advantages, the pipes.

Filters used to act like helpers, very similar to functions where you pass the input and other parameters and it returns you the value; but pipe works as a operator. The concept is, you have an input and you can modify the input applying multiple pipes in it. This not only simplifies the nested pipe logic, but also gave you a beautiful and clean syntax for your templates. Secondly, in case of async operations, you need to set things manually in case of angular 1.X filters. But pipes are smart enough to handle async operations.

References :

  1. wikipedia.org wiki pages for Pipe
  2. “AngularJS” Author Brad Green, Shyam Seshadri and Published by O’Reilly Media, Inc.
  3. “Switching to Angular 2” Author Minko Gechev and Published by Packt Publishing Ltd.
  4. Angular 2 Series – Part 1: Working with Pipes by Ryan Chenkie
  5. Angular 2 pipes in depth; with list of inbuilt pipes and examples by Paul Shan