To improve readability instead of displaying full numbers very often there is a need to display shortened numbers. Here is an example of how to create your own customisable short number pipe in Angular8.
Pipe in Angular is a data processing element which is used in a presentation layer (in a template). All pipes must implement PipeTransform interface. PipeTransform interface contains a method called “transform()” which is invoked by Angular with a value passed as a first argument and optional parameters as a second argument.
Pipes can be joined into a set of pipes. In such case output of the previous pipe will be input for the next one.
{{item.count | shortNumber}} is an example of how pipe may be used in your templates to change item.count representation.
Task: Display text “1.5M” instead of 1500000 in the view.
Solution: generate custom pipe and implement short number functionality.
A command to generate new shortNumber pipe in pipes/ directory:
ng generate pipe pipes/shortNumber
The command above creates pipes/short-number.pipe.ts file and registers ShortNumberPipe in modules declarations.
// short-number.pipe.ts
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'shortNumber'
})
export class ShortNumberPipe implements PipeTransform {
transform(value: any, args?: any): any {
return null;
}
}
ShortNumberPipe class must implement PipeTransform interface which is common interface for all Angular pipes.
PipeTransform interface requires single transform() method to be implemented. See short number functionality implementation below.
transform(value: any, args?: any): any {
if (value === null) return null;
if (value === 0) return "0";
var fractionSize = 1;
var abs = Math.abs(value);
var rounder = Math.pow(10, fractionSize);
var isNegative = value < 0;
var key = '';
var powers = [{ key: "Q", value: Math.pow(10, 15) }, { key: "T", value: Math.pow(10, 12) }, { key: "B", value: Math.pow(10, 9) }, { key: "M", value: Math.pow(10, 6) }, { key: "k", value: 1000 }];
for (var i = 0; i < powers.length; i++) {
var reduced = abs / powers[i].value;
reduced = Math.round(reduced * rounder) / rounder;
if (reduced >= 1) {
abs = reduced;
key = powers[i].key;
break;
}
}
return (isNegative ? '-' : '') + abs + key;
}
In the example above “Q” stands for quadrillion, “T” — trillion, “B” — billion, “M” — million, “k” — kilo.
And hardcoded fractionSize defines the precision of rounding numbers. You are welcome to adjust it to your needs.
Lets check the result with this piece of html:
<span class=”cnt-wrap”>{{1500000 | shortNumber}}</span>
After interpolation it displays 1.5M. And if substitute 1500000 with 15300 the result of number transformation will be 15.3k.
Done!
As your homework, make shortNumber pipe parametrised. For instance, you can do this with a fractionSize passed as an argument. Take a look in the docs for help.
After the changes, {{1520000 | shortNumber:2}} must produce 1.52M (fractionSize is set to 2).
Tip: before starting a new pipe, check for existing one in built-in pipes! However, the list of available pipes isn’t big yet.
Hopefully, this article was useful! Thanks for reading!
Previously published at https://medium.com/front-end-weekly/creating-a-short-number-format-pipe-in-angular-8a2c973c87c2