DEV Community

Bearded JavaScripter
Bearded JavaScripter

Posted on • Edited on

2 1

Use Pipes in your next Angular Application! (Part 2)

Pipes are a pretty useful feature of Angular that allow us to transform the way we display data to our user without actually altering the data. Many times we may want to display dates, money, currency or just numbers in a preferred format.

This article is a continuation of my first post about pipes here where we got familiar with the simpler pipes:

  • Case-based pipes
    • UpperCasePipe
    • LoweCasePipe
    • TitleCasePipe
  • Number-based pipes
    • DecimalPipe
    • PercentPipe
    • CurrencyPipe

We'll be looking at 3 more pipes in this article, namely:

TL;DR: Here's the sample project with all the code

JsonPipe

This pipe gives us a simple way to display complex data straight to our template. While we're not accustomed to showing raw JSON data for our users to see, Angular mentions in their documentation that this pipe is useful for debugging. I've personally found it immensely useful for displaying the value of a Reactive Form while changing the values.

Let's look at a general example:

import { Component } from '@angular/core';
@Component({
selector: 'app-json-pipe',
template: `
<p>Object: {{data}}</p>
<p>Object with JsonPipe: {{data | json}}</p>
<p>array: {{array}}</p>
<p>array: {{array | json}}</p>
`,
styleUrls: []
})
export class JsonPipeComponent {
data: object = {
name: 'Qarun', age: 25, food: 'Cheesecake',
languages: [
{ name: 'JavaScript', proficiency: 'Wizard' },
{ name: 'Python', proficiency: 'Avergae' },
{ name: 'Elixir', proficiency: 'Beginner'}
]
};
array: number[] = [1,2,3,4,5,6];
}

And the corresponding output:

Object: [object Object]

Object with JsonPipe: { "name": "Qarun", "age": 25, "food": "Cheesecake", "languages": [ { "name": "JavaScript", "proficiency": "Wizard" }, { "name": "Python", "proficiency": "Avergae" }, { "name": "Elixir", "proficiency": "Beginner" } ] }

array: 1,2,3,4,5,6

array: [ 1, 2, 3, 4, 5, 6 ]
Enter fullscreen mode Exit fullscreen mode

Displaying the object from the component directly into the HTML causes the raw string version to be shown. This is achieved by JavaScript automatically running data.toString(), hence the [object Object] in the examples without the pipe.

However, with the JsonPipe, it runs the variable through JSON.stringify, which is why our object shows properly and why the array with the pipe has brackets.

SlicePipe

You're probably familiar with the Array slice and the String slice methods in Vanilla JavaScript. They both slice out and return a specified portion of the Array/String.

Angular offers us a SlicePipe which works the same way, allowing us to manipulate with strings and arrays directly in our HTML template. It even allows us to change an array that *ngFor is applied to.

import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-slice-pipe',
template: `
<p>Short String: {{shortString}}</p>
<p>Short String with Slice Pipe: {{shortString | slice: 0:2}}</p>
<p>Long string (Characters 10-19 inclusive): {{longString | slice: 10:20}}</p>
<p *ngIf = 'showLongString; else shortStringTemplate'>{{longString}}</p>
<ng-template #shortStringTemplate>
<p>{{longString | slice: 0: 50}}...</p>
</ng-template>
<button (click) = "toggleLongString()">{{showLongString ? "Show Short String" : "Show Long String"}}</button>
<p>{{numbers | slice: 0: 4}}</p>
<p>{{numbers | slice: 0: 4 | json}}</p>
`,
styleUrls: []
})
export class SlicePipeComponent {
shortString: string = 'My name is Qarun';
longString: string = `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.`;
showLongString: boolean = false;
numbers: number[] = [0,1,2,3,4,5,6,7,8,9];
toggleLongString() {
this.showLongString = !this.showLongString;
}
}

The above example shows one of the many use cases for the SlicePipe: hiding a long string. A button or "Read more" text can be clicked to show the full string. It's also useful if you want to build your own pagination when applied to *ngFor.
Notice how in the very last array example, we included the JsonPipe at the end. Pipes can be chained together.

KeyValuePipe

Another useful Pipe is the KeyValuePipe which allows is to display objects. This is similar to the JsonPipe but with a slight twist. It automatically sorts the object by keys.

Usually, the process of displaying an object's sorted contents goes something like this:

  • Get the object from some source in your TypeScript
  • Use Object.keys, Object.values, or Object.entries
  • Sort resulting array into a new array
  • Loop through new, sorted array and display values

KeyValuePipe cuts down that process by 50%. All you need is your comparator function and Angular does the rest. By allowing us to supply the comparator function, we still have the power to sort complex data structures. If no function is provided, then defaultComparator is used.

import { Component } from '@angular/core';
import { KeyValue } from '@angular/common';
interface Item {
name: string;
price: number;
expDate: number;
}
@Component({
selector: 'app-key-value-pipe',
template: `
<h3>Default Key-Value pipe</h3>
<p *ngFor = "let item of person | keyvalue">
{{item.key}} - {{item.value}}
</p>
<h3>Custom Sort functions:</h3>
<h4>Sort by decreasing length of string values</h4>
<p *ngFor = "let item of person | keyvalue:customCompareFn">
{{item.key}} - {{item.value}}
</p>
<h4>Sort by increasing expiry dates</h4>
<p *ngFor = 'let item of inventory | keyvalue:increasingExpDate'>
{{item.value.name}} expires at {{item.value.expDate | date}}
</p>
`,
styleUrls: []
})
export class KeyValuePipeComponent {
person: object = {
name: 'Qarun',
age: '25',
food: 'Cheesecake'
};
milliseconds: number = 1000 * 60 * 60 * 24;
inventory: Item[] = [
{
name: 'Cabbage',
price: 5,
expDate: Date.now() + (this.milliseconds * 14)
},
{
name: 'Lettuce',
price: 10,
expDate: Date.now() + (this.milliseconds * 21)
},
{
name: 'Tomatoes',
price: 15,
expDate: Date.now() + (this.milliseconds * 17)
},
]
constructor() { }
customCompareFn(a: KeyValue<string, string>, b: KeyValue<string, string>) {
if (a.value.length > b.value.length) return -1;
if (a.value.length === b.value.length) return 0;
if (a.value.length < b.value.length) return 1;
}
increasingExpDate(a: KeyValue<number, Item>, b: KeyValue<number, Item>) {
if (a.value.expDate < b.value.expDate) return -1;
if (a.value.expDate === b.value.expDate) return 0;
if (a.value.expDate > b.value.expDate) return 1;
}
}

And the corresponding output:

Key-Value Pipes!

Default Key-Value pipe
age - 25
food - Cheesecake
name - Qarun

Custom Sort functions:

Sort by decreasing length of string values
food - Cheesecake
name - Qarun
age - 25

Sort by increasing expiry dates
Cabbage expires at Apr 14, 2020
Tomatoes expires at Apr 17, 2020
Lettuce expires at Apr 21, 2020
Enter fullscreen mode Exit fullscreen mode

In the code above, I displayed 3 examples:

  • Default KeyValuePipe
  • Sorting by decreasing length of strings
  • Sorting by increasing Expiry Date

The power of this pipe is only limited by your comparator function. Also, If you're wondering how my dates are displayed in such a readable format, that's because of the DatePipe which I'll be covering as part of my next Article :)

Conclusion

You've made it to the end! In this article, we covered:

  • JsonPipe
  • SlicePipe
  • KeyValuePipe

Thanks a lot for reading! Look out for my next article on some more exciting pipes :D

AWS GenAI LIVE image

Real challenges. Real solutions. Real talk.

From technical discussions to philosophical debates, AWS and AWS Partners examine the impact and evolution of gen AI.

Learn more

Top comments (0)

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay