Angular 2 — Let’s talk about pipes (ng-filter in Angular 1)

Carlos Menezes
Frontend Weekly
Published in
5 min readMar 20, 2016

What are pipes on Angular 2?

Pipes allow us to change data inside of a template; i.e. filtering, ordering, formatting dates, numbers, currencies, etc. A quick example is you can transfer a string to lowercase by applying a simple filter in the template code.

In Angular 1.x pipes are named ‘filters’ and if it is familiar to you, a pipe can be used in either HTML or in your own code.

Usage of pipes and why to use them?

Pipes are accessed in the template code by using the pipe character | (the same syntax as in Angular 1.x), and then the name of the pipe you want to use. The expression is evaluated and the result goes through the pipe; it is a simple and reusable way to transform data within a template.

Pipes are chaining, so you can use multiple combination of pipes. Example:

<p>{{ cars | slice:0:2 | json }}</p>

We will come back to the slice and json pipe soon.

How many standard pipes does Angular 2 offer us?

9 so far, so we have:

1. JsonPipe

Probably not very useful but very handy when we are debugging the app. JsonPipe applies JSON.stringify() to our data. If you have already worked with json you will know what the JSON.stringify() method does.

Imagine we have some data in our component, an array of something called cars and we want to see what is inside; you could try something like this:

<p> {{ cars }}</p>

Tough! It is going to display [object Object]

Using JsonPipe:

<p> {{ cars | json }}</p>

BOOMMM! It will display the JSON representation of the object:

<p>[ { "id": 1, "name":"BMW" }, { "id": 2, "name": "Suzuki" } ]</p>

You can use pipes in an interpolation expression (example above {{ cars | json}}) or in a property expression, but not in an event statement. Let’s see how we use it in a property expression:

<p [textContent]="cars | json"></p>

We can talk about syntax template in the next article. But here you can find an excellent article talking about it.

How can we use pipes via dependency injection inside our component?

import {Component} from 'angular2/core';
// Importing the pipe we want to use;
import {JsonPipe} from 'angular2/common';
@Component({
selector: 'list-cars',
template: `<p>{{jsonCars}}</p>`
})
class AppComponent {
cars:Array<any> =[{id:1, name:'BMW'},{id:2, name: 'Suzuki'}];
jsonCars : string;
// Injecting the pipe
constructor(private jsonPipe: JsonPipe) {
// Calling the transform method
this.jsonCars = jsonPipe.transform(this.cars);
}
}

2. SlicePipe:

Description: Allows us to display part of a list.

Expression:

expression | slice:start[:end]

Example:

<p>{{ cars | slice:0:2 }}</p>

This example will display the first two elements of the list of cars.

Slice works with arrays, NgFor, and strings, so you can truncate strings if you want:

<p>{{ 'Carlos Menezes' | slice:0:5 }}</p>
<!-- will display 'Carlos' -->

3. uppercase:

Description: Transforms a string into uppercase.

Example:

<p>{{ 'Carlos Menezes' | uppercase }}</p>
<!-- will display 'CARLOS MENEZES' -->

4. lowercase:

Description: Transforms a string into lowercase.

Example:

<p>{{ 'Carlos Menezes' | uppercase }}</p>
<!-- will display 'carlos menezes' -->

5. number:

Description: Allows us to format a number:

Expression:

expression | number[:digitInfo]

Example:

<p>{{ 98745 }}</p>
<! — will display '98745' →

Using the pipe:

<p>{{ 98745 | number }}</p>
<!— will display '98,745' →

6. percent:

Description: Allows us to display a percentage.

Example:

<p>{{ 0.5 | percent }}</p>
<!-- will display '50%' -->

7. date:

Description: Allows us to format dates values into a string.

Example:

<p>{{ dateOfBirthday | date:'ddMMyyyy' }}</p>
<!-- will display '13/06/1985' -->
<p>{{ dateOfBirthday | date:'longDate' }}</p>
<!-- will display 'June 13, 1985' -->
<p>{{ dateOfBirthday | date:'HHmmss' }}</p>
<!-- will display '03:45:15' -->
<p>{{ dateOfBirthday | date:'shortTime' }}</p>
<!-- will display '03:45 AM' -->

8. async:

Description: Allows us to display data asynchronously.

This pipe can display data using PromisePipe or ObservablePipe depending on whether the data comes from a Promise or Observable.

Example:

// importing the pipe we want to use;
import {Component} from 'angular2/core';
@Component({
selector: 'list-cars',
template: `<p>{{asyncHello | async}}</p>`
})
class AppComponent {
asyncHello: Promise<string> = new Promise(resolve => {
// after 1 second, BOOOMM!!
window.setTimeout(() => resolve('Hiya Angular 2'), 1000);
});
}

9. currency:

Description: Allows us to format an amount of money into currency.

Example:

<p>{{ 51.5 | currency:'EUR' }}</p>
<! — will display 'EUR51.5' →
<p>{{ 51.5 | currency:'USD':true }}</p>
<! — will display '$51.5' →
<p>{{ 51.5 | currency:'USD':true:'.2' }}</p>
<! — will display '$51.50' →

How to create and use a custom pipe?

Creating a custom Pipe is as simple as giving it a name and a transform function that gives you the intended output.

Example:

To create a pipe you will need to:

  1. Create a new class adding the keyword export. (line 6)
  2. Import from ‘angular2/core’ the module Pipe and PipeTransform. (line 1)
  3. Add the @Pipe annotation to your class and set the name of the pipe. (line 3 & 4)
  4. Implement PipeTransform (line 6)
  5. Implement the transform(value, args). (line 7)

As best practice, I recommend that you always use the “PipeTransform” interface, which forces us to have a transform() method.

How do you make the custom pipe available everywhere?

To use the pipe in a template; from your @Component decorator for example, you have to declare your custom pipe from the pipes attribute:

import {Component} from 'angular2/core';
import {CarService} from './carService';
// importing the pipe we want to use;
import {StartedPipe} from 'started.pipe';
@Component({
selector: 'list-cars',
template: `
<ul>
<li *ngFor="#car of cars | started">{{car.name}}</li>
</ul>
`
pipes:[StartedPipe] // making the pipe available for the template
})
class AppComponent {
cars:Array<any>;
constructor(private _carService: CarService) {
this.cars = _carService.getCars();
}
}

To make the custom pipe available everywhere in your application (because you use it several time and you do not want to declare it every time in the pipes attribute) you have to add it to the collection called PLATFORM_PIPES that contains all the pipes we mentioned above:

bootstrap([
provide(PLATFORM_PIPES, {useValue: StartedPipe, multi: true})
])

In one of my previous articles, I explained the use of providers, have a look.

Using the provider, we don’t have to declare the pipes attribute anymore in the component:

import {Component} from 'angular2/core';
import {CarService} from './carService';
@Component({
selector: 'list-cars',
template: `
<ul>
<li *ngFor="#car of cars | started">{{car.name}}</li>
</ul>
`
})
class AppComponent {
cars:Array<any>;
constructor(private _carService: CarService) {
this.cars = _carService.getCars();
}
}

Let’s see an example of how we create a filter on Angular 1 and pipes on Angular 2 called “todoStatuses” using Angular 1.x way and Angular 2 way:

The Angular 1.x way:

The Angular 2 way:

Happy coding! 😃

References:

--

--

Carlos Menezes
Frontend Weekly

Full-stack & Software Engineer, Javascript, Angular, MVC, C# and all other web things ✌ ☃ London ☂ ☁ 🇸🇹 > 🇵🇹 > 🇪🇸 > 🇬🇧