{"id":1615,"date":"2024-05-31T22:00:00","date_gmt":"2024-05-31T20:00:00","guid":{"rendered":"https:\/\/demo.sidekick.be\/itenium\/angular-pipes\/"},"modified":"2025-11-28T13:31:45","modified_gmt":"2025-11-28T12:31:45","slug":"angular-pipes","status":"publish","type":"post","link":"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/angular-pipes\/","title":{"rendered":"Angular Pipes"},"content":{"rendered":"<h1 id=\"builtin-pipes\">Builtin Pipes<\/h1>\n<h2 id=\"jsonpipe-impure\">JsonPipe <small>(Impure)<\/small><\/h2>\n<p>Quick object dump with the <strong>impure JsonPipe<\/strong>.<\/p>\n<p class=\"notice--info\"><strong>Impure<\/strong>: Angular executes an impure pipe during every component change detection cycle. An impure pipe is called often, as often as every keystroke or mouse-move.<\/p>\n<p style=\"float: right\"><a href=\"https:\/\/angular.dev\/api\/common\/JsonPipe\">JsonPipe API<\/a><\/p>\n<p>Example usage:<\/p>\n<pre><code class=\"language-html\">&lt;pre&gt;{{ {number: 7} | json }}&lt;\/pre&gt;\n\n&lt;!-- Combine with the AsyncPipe to dump Observables --&gt;\n&lt;code&gt;{{ observable$ | async | json }}&lt;\/code&gt;\n<\/code><\/pre>\n<p>Inject in a Component:<\/p>\n<pre><code class=\"language-ts\">import { CurrencyPipe, formatCurrency } from '@angular\/common';\n\n@Component({\n  providers: [CurrencyPipe]\n})\nexport class AppComponent {\n  constructor(private cp: CurrencyPipe) {\n    this.cp.transform(450.657, 'EUR', 'symbol', '0.2-2', 'fr'); \/\/ 450,66\u00a0\u20ac\n\n    \/\/ Use the formatCurrency instead! (formatDate, formatNumber, ...)\n    formatCurrency(450.657, 'fr', 'EUR', 'symbol', '0.2-2');\n  }\n}\n<\/code><\/pre>\n<h2 id=\"string-casing-pipes\">String Casing Pipes<\/h2>\n<p><a href=\"https:\/\/angular.dev\/api\/common\/UpperCasePipe\">UpperCasePipe<\/a> , <a href=\"https:\/\/angular.dev\/api\/common\/LowerCasePipe\">LowerCasePipe<\/a> and <a href=\"https:\/\/angular.dev\/api\/common\/TitleCasePipe\">TitleCasePipe<\/a>.<\/p>\n<pre><code class=\"language-html\">lowercase =&gt; {{ 'LOWERCASE' | lowercase }}\n\nUPPERCASE =&gt; {{ 'uppercase' | uppercase }}\n\nThis Is Title Case =&gt; {{ 'tHIs is tiTLE CaSe' | titlecase }}\n<\/code><\/pre>\n<h2 id=\"locale-sensitive-pipes\">Locale Sensitive Pipes<\/h2>\n<p>Used by <strong>DatePipe<\/strong>, <strong>CurrencyPipe<\/strong>, <strong>DecimalPipe<\/strong> and <strong>PercentPipe<\/strong>.<\/p>\n<h3 id=\"setup\">Setup<\/h3>\n<p style=\"float: right\"><a href=\"https:\/\/angular.dev\/guide\/i18n\">Official i18n docs<\/a><\/p>\n<p>By default, Angular comes with the <code>en-US<\/code> locale only. Import a different locale in your <code>app.module.ts<\/code>:<\/p>\n<pre><code class=\"language-typescript\">import { registerLocaleData } from '@angular\/common';\nimport { LOCALE_ID, NgModule } from '@angular\/core';\nimport localeFr from '@angular\/common\/locales\/fr';\n\nregisterLocaleData(localeFr, 'fr');\n\n@NgModule({\n  providers: [\n    {provide: DEFAULT_CURRENCY_CODE, useValue: 'EUR'}, \/\/ default: USD\n    {provide: LOCALE_ID, useValue: 'fr'}, \/\/ default: en-US\n    \/\/ default dateFormat: mediumDate\n    \/\/ default timezone: user local system timezone\n    {provide: DATE_PIPE_DEFAULT_OPTIONS, useValue: {dateFormat: 'MM\/dd\/yy', timezone: '-1200'}},\n  ],\n})\nexport class AppModule { }\n<\/code><\/pre>\n<p>Or without module:<\/p>\n<pre><code class=\"language-ts\">import { ApplicationConfig } from '@angular\/core';\n\nexport const appConfig: ApplicationConfig = {\n  providers: [\n    {provide: LOCALE_ID, useValue: 'fr'},\n    {provide: DEFAULT_CURRENCY_CODE, useValue: 'EUR'},\n    {provide: DATE_PIPE_DEFAULT_OPTIONS, useValue: {dateFormat: 'MM\/dd\/yy', timezone: '-1200'}},\n  ]\n};\n\nbootstrapApplication(AppComponent, appConfig);\n<\/code><\/pre>\n<h3 id=\"currencypipe\">CurrencyPipe<\/h3>\n<p style=\"float: right\"><a href=\"https:\/\/angular.dev\/api\/common\/CurrencyPipe\">CurrencyPipe API<\/a><\/p>\n<p>Outside html templates, use <a href=\"https:\/\/angular.dev\/api\/common\/formatCurrency\"><code>formatCurrency()<\/code><\/a> instead!<\/p>\n<pre><code class=\"language-html\">&lt;!-- Signature --&gt;\n{{ value_expression | currency [ : currencyCode [ : display [ : digitsInfo [ : locale ] ] ] ] }}\n\n&lt;!-- Examples --&gt;\n\u20ac1,500.95 =&gt; {{ 1500.953 | currency:'EUR':'symbol' }}\n\n003,96 EUR =&gt; {{ 3.955 | currency:'EUR':'code':'3.2-2':'fr' }}\n<\/code><\/pre>\n<p>Parameters:<\/p>\n<ul>\n<li>currencyCode: USD, EUR, GBP, \u2026 (<a href=\"https:\/\/en.wikipedia.org\/wiki\/ISO_4217#Active_codes\">full list<\/a>)<\/li>\n<li>display: code=USD, symbol=$, a string<\/li>\n<li>digitsInfo: [minIntegerDigits=1].[minFractionDigits=2]-[maxFractionDigits=2] (ex: 3.2-2 -&gt; 000.00)<\/li>\n<li>locale: en-US<\/li>\n<\/ul>\n<p>Parameters <code>digitsInfo<\/code> and <code>locale<\/code> work exactly the same for DecimalPipe and PercentPipe.<\/p>\n<p style=\"float: right\"><a href=\"https:\/\/angular.dev\/api\/common\/DecimalPipe\">DecimalPipe API<\/a><\/p>\n<h3 id=\"decimalpipe\">DecimalPipe<\/h3>\n<p>Outside html templates, use <a href=\"https:\/\/angular.dev\/api\/common\/formatNumber\"><code>formatNumber()<\/code><\/a> instead!<\/p>\n<pre><code class=\"language-html\">&lt;!-- Signature --&gt;\n{{ value_expression | number [ : digitsInfo [ : locale ] ] }}\n\n&lt;!-- Example --&gt;\n025.1230 =&gt; {{ 25.123 | number:'3.4-4'}}\n<\/code><\/pre>\n<p style=\"float: right\"><a href=\"https:\/\/angular.dev\/api\/common\/PercentPipe\">PercentPipe API<\/a><\/p>\n<h3 id=\"percentpipe\">PercentPipe<\/h3>\n<p>Use <a href=\"https:\/\/angular.dev\/api\/common\/formatPercent\"><code>formatPercent()<\/code><\/a> outside templates.<\/p>\n<pre><code class=\"language-html\">&lt;!-- Signature --&gt;\n{{ value_expression | percent [ : digitsInfo [ : locale ] ] }}\n\n&lt;!-- Example --&gt;\n26% =&gt; {{ 0.259 | percent }}\n<\/code><\/pre>\n<h3 id=\"datepipe\">DatePipe<\/h3>\n<p style=\"float: right\"><a href=\"https:\/\/angular.dev\/api\/common\/DatePipe\">DatePipe API<\/a><\/p>\n<p>Works on a <code>Date<\/code>, a number (ms since UTC epoch), or an <a href=\"https:\/\/www.w3.org\/TR\/NOTE-datetime\">ISO string<\/a><br \/> Use <a href=\"https:\/\/angular.dev\/api\/common\/formatDate\"><code>formatDate()<\/code><\/a> outside templates instead!<\/p>\n<p>All functions like <code>getLocaleDayNames<\/code> etc have been deprecated in favor of using <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Intl\"><code>Intl<\/code><\/a>.<\/p>\n<pre><code class=\"language-html\">&lt;!-- Signature --&gt;\n{{ value_expression | date [ : format [ : timezone [ : locale ] ] ] }}\n\n&lt;!-- Basic examples --&gt;\nMay 1, 2019 =&gt; {{ Date.parse('2019-05-01') | date }}\n2019-05-01 23:55:00 =&gt; {{ Date.parse('2019-05-01T23:55:00') | date:'yyyy-MM-dd HH:mm:ss' }}\n\n&lt;!-- Full blown example --&gt;\n1 mai 2019, 21h00 =&gt; {{ Date.parse('2019-05-01T23:55:00') | date:\"d MMMM yyyy, HH'h'mm\":'-0055':'fr' }}\n<\/code><\/pre>\n<p>More options for the format:<\/p>\n<ul>\n<li>Escape characters by placing them inside single quotes<\/li>\n<li><strong>Week of year<\/strong>: w=7, ww=07<\/li>\n<li><strong>Week day<\/strong>: E=Tue, EEEE=Tuesday, EEEEE=T, EEEEEE=Tu<\/li>\n<li><strong>Month<\/strong> standalone: LLLL=September<\/li>\n<li><strong>Period<\/strong>: a=am\/pm<\/li>\n<li><strong>Hour 1-12<\/strong>: h=1, hh=01<\/li>\n<li><strong>Zone<\/strong>: z=GMT-8, Z=-0800<\/li>\n<li>Or named: short, medium, long, full; shortDate, mediumDate (default), longTime, \u2026<\/li>\n<\/ul>\n<h2 id=\"array-pipes\">Array Pipes<\/h2>\n<p style=\"float: right\"><a href=\"https:\/\/angular.dev\/api\/common\/SlicePipe\">SlicePipe API<\/a><\/p>\n<h3 id=\"slicepipe-impure\">SlicePipe <small>(Impure)<\/small><\/h3>\n<pre><code class=\"language-html\">&lt;!-- Signature --&gt;\n{{ value_expression | slice : start [ : end ] }}\n\n&lt;!-- Examples --&gt;\n[ 0, 1 ] =&gt; {{ [0, 1, 2, 3, 4] | slice:0:2 | json }}\n  \n[ 4 ] =&gt; {{ [0, 1, 2, 3, 4] | slice:-1 | json }}\n\n[ 0, 1 ] =&gt; {{ [0, 1, 2, 3, 4] | slice:-5:2 | json }}\n\n[ 0, 1, 2 ] =&gt; {{ [0, 1, 2, 3, 4] | slice:-5:-2 | json }}\n<\/code><\/pre>\n<h3 id=\"keyvaluepipe-impure\">KeyValuePipe <small>(Impure)<\/small><\/h3>\n<p style=\"float: right\"><a href=\"https:\/\/angular.dev\/api\/common\/KeyValuePipe\">KeyValuePipe API<\/a><\/p>\n<p>Works on Objects and Maps.<\/p>\n<pre><code class=\"language-html\">&lt;div *ngFor=\"let item of object | keyvalue:compareFn\"&gt;\n    {{item.key}} =&gt; {{item.value}}\n&lt;\/div&gt;\n<\/code><\/pre>\n<p>The optional <code>compareFn<\/code> parameter signature defined in <code>component.ts<\/code>:<\/p>\n<pre><code class=\"language-typescript\">export class AppComponent {\n    object = {key1: 1, key2: 2};\n\n    \/\/ revert sorting of this.object keys\n    \/\/ interface KeyValue&lt;K, V&gt;{key: K, Value: V}\n    compareFn(a: KeyValue&lt;string, number&gt;, b: KeyValue&lt;string, number&gt;) {\n        return b.key.localeCompare(a.key);\n    }\n}\n<\/code><\/pre>\n<p>The output would be:<\/p>\n<ul>\n<li><code>let item of object | keyvalue:compareFn<\/code>: <code>key2 =&gt; 2<\/code> and <code>key1 =&gt; 1<\/code><\/li>\n<li><code>let item of object | keyvalue<\/code>: <code>key1 =&gt; 1<\/code> and <code>key2 =&gt; 2<\/code><\/li>\n<\/ul>\n<h2 id=\"asyncpipe-impure\">AsyncPipe <small>(Impure)<\/small><\/h2>\n<p style=\"float: right\"><a href=\"https:\/\/angular.dev\/api\/common\/AsyncPipe\">AsyncPipe API<\/a><\/p>\n<p>Returns the last emitted value. Unsubscribes automatically in <code>ngOnDestroy<\/code>.<\/p>\n<p>I typically <strong>always<\/strong> use the <code>AsyncPipe<\/code> instead of <code>.subscribe()<\/code> in TS.<br \/> Do keep track on your DevTools Network Tab though, make sure you are not performing the same http call multiple times when rendering a component!<\/p>\n<pre><code class=\"language-html\">Time: {{ time$ | async }}\n\n&lt;!-- Capture the value without re-evaluating time$ --&gt;\n&lt;div *ngIf=\"time$ | async as time; else loading\"&gt;\n    {{ time }}\n&lt;\/div&gt;\n&lt;ng-template #loading&gt;\n    Waiting...\n&lt;\/ng-template&gt;\n<\/code><\/pre>\n<p>Where <code>time$<\/code> is an Observable or a Promise. Ex:<\/p>\n<pre><code class=\"language-typescript\">export class AppComponent {\n  time$ = interval(1000).pipe(\n    map(() =&gt; new Date().toString())\n  )\n}\n<\/code><\/pre>\n<h2 id=\"i18n-pipes\">i18n Pipes<\/h2>\n<p style=\"float: right\"><a href=\"https:\/\/angular.dev\/api\/common\/I18nPluralPipe\">I18nPluralPipe API<\/a><\/p>\n<h3 id=\"i18npluralpipe\">I18nPluralPipe<\/h3>\n<p>Display \u201c1 item\u201d but \u201c2 items\u201d, check the structure <a href=\"https:\/\/unicode-org.github.io\/icu\/userguide\/format_parse\/messages\/#complex-argument-types\">here<\/a>.<\/p>\n<pre><code class=\"language-ts\">{{ some_number | i18nPlural: pluralItemsMap }}\n\nconst pluralItemsMap = {\n  '=0': 'zero items',\n  '=1': 'one item',\n  'other': '# items',\n}\n<\/code><\/pre>\n<p style=\"float: right\"><a href=\"https:\/\/angular.dev\/api\/common\/I18nSelectPipe\">I18nSelectPipe API<\/a><\/p>\n<h3 id=\"i18nselectpipe\">I18nSelectPipe<\/h3>\n<pre><code class=\"language-ts\">{{ 'F' | i18nSelect: genderMap }}\n\nconst genderMap = {\n  'M': 'Mr',\n  'F': 'Ms',\n  'X': 'Mx',\n}\n<\/code><\/pre>\n<h1 id=\"custom-pipes\">Custom Pipes<\/h1>\n<p>Create your own pipes for displaying values relevant in your application domain.<\/p>\n<h2 id=\"creation\">Creation<\/h2>\n<p>Use <a href=\"https:\/\/angular.dev\/cli\/generate\/pipe\"><code>ng generate<\/code><\/a><\/p>\n<pre><code class=\"language-powershell\">ng g pipe &lt;name&gt; options\n<\/code><\/pre>\n<p>Options:<\/p>\n<ul>\n<li><code>--export=false<\/code>: Add to module declarations and exports?<\/li>\n<li><code>--flat=true<\/code>: Write at the top level of the project<\/li>\n<li><code>--lintFix=false<\/code><\/li>\n<li><code>--module=<\/code> and <code>--project=<\/code><\/li>\n<li><code>--skipImport=false<\/code> and <code>--skipTests=false<\/code><\/li>\n<\/ul>\n<h2 id=\"example\">Example<\/h2>\n<pre><code class=\"language-typescript\">import { Pipe, PipeTransform } from '@angular\/core';\n\n\/\/ Usage: \n\/\/ 15:30 =&gt; {{ someDate | hours }}\n\/\/ 15h =&gt; {{ someDate | hours:true:false  }}\n\n@Pipe({name: 'hours', pure: true})\nexport class HoursPipe implements PipeTransform {\n  transform(value: Date, showHours = true, showMinutes = true): string {\n    value = new Date(value);\n    if (showMinutes) {\n      return value.getHours() + ':' + value.getMinutes();\n    }\n    return value.getHours() + 'h';\n  }\n}\n<\/code><\/pre>\n<h2 id=\"installation\">Installation<\/h2>\n<p>If you didn\u2019t use <code>ng generate<\/code>.<\/p>\n<pre><code class=\"language-typescript\">@NgModule({\n  declarations: [AppComponent, CustomPipe],\n  exports: [CustomPipe] \/\/ Also add to `exports` when declaring in a shared module.\n})\n<\/code><\/pre>\n<h2 id=\"testing\">Testing<\/h2>\n<p>Run tests with <code>ng test<\/code>.<\/p>\n<pre><code class=\"language-typescript\">import { HoursPipe } from '.\/hours.pipe';\n\ndescribe('HoursPipe', () =&gt; {\n  const someDate = new Date('2000-01-01T15:30:00');\n  let pipe: HoursPipe;\n\n  beforeEach(() =&gt; {\n    pipe = new HoursPipe();\n  });\n\n  it('shows h:M by default', () =&gt; {\n    const result = pipe.transform(someDate);\n    expect(result).toBe('15:30');\n  });\n\n  it('shows 15h with arguments {{ value | hours:true:false }}', () =&gt; {\n    const result = pipe.transform(someDate, true, false);\n    expect(result).toBe('15h');\n  });\n});\n<\/code><\/pre>\n<h1 id=\"real-world-examples\">Real World Examples<\/h1>\n<p>Some custom examples to get in the right mind what Pipes could be useful for.<\/p>\n<h2 id=\"nl2brpipe\">Nl2brPipe<\/h2>\n<p>Convert newlines in string resources to <code>&lt;br&gt;<\/code>s.<\/p>\n<pre><code class=\"language-typescript\">import { Pipe, PipeTransform } from '@angular\/core';\n\n\/\/ Usage: &lt;div [innerHTML]=\"'Line1nLine2' | nl2br\"&gt;&lt;\/div&gt;\n\n\/\/ Combine with ngx-translate\n\/\/ Usage: &lt;div [innerHTML]=\"'resource.key' | translate | nl2br\"&gt;&lt;\/div&gt;\n\n@Pipe({name: 'nl2br'})\nexport class Nl2brPipe implements PipeTransform {\n  transform(value: string): string {\n    return value.replace(\/n\/g, '&lt;br \/&gt;');\n  }\n}\n<\/code><\/pre>\n<h2 id=\"ucfirstpipe\">UCFirstPipe<\/h2>\n<p>While <code>capitalize<\/code> (capitalize each word) is bundled with Angular, one to capitalize just the first letter is not.<\/p>\n<pre><code class=\"language-typescript\">@Pipe({ name: 'ucfirst' })\nexport class UcFirstPipe implements PipeTransform {\n   transform(text: any): string {\n     if (typeof text !== 'string') {\n       return text;\n     }\n    return text.slice(0, 1).toUpperCase() + text.slice(1);\n  }\n}\n<\/code><\/pre>\n<h2 id=\"bytespipe\">BytesPipe<\/h2>\n<p>Fancy display of filesizes etc.<\/p>\n<pre><code class=\"language-typescript\">\/\/ Usage: 1024\n\n@Pipe({ name: 'bytes' })\nexport class BytesPipe implements PipeTransform {\n  private dict: Array&lt;{max: number; type: string}&gt; = [\n    { max: 1024, type: 'B' },\n    { max: 1048576, type: 'KB' },\n    { max: 1073741824, type: 'MB' },\n    { max: 1.0995116e12, type: 'GB' },\n  ];\n\n  transform(value: number, precision: number = 0): string | number {\n    if (isNaN(parseFloat(String(value))) || !isFinite(value)) {\n      return NaN;\n    }\n\n    const format = this.dict.find(d =&gt; value &lt; d.max) || this.dict[this.dict.length - 1];\n    const calc = value \/ (format.max \/ 1024);\n    const num = this.applyPrecision(calc, precision);\n\n    return `${num}${format.type}`;\n  }\n\n  applyPrecision(num: number, precision: number) {\n    if (precision &lt;= 0) {\n      return Math.round(num);\n    }\n\n    const tho = 10 ** precision;\n    return Math.round(num * tho) \/ tho;\n  }\n}\n<\/code><\/pre>\n<h2 id=\"ngx-pipes\">ngx-pipes<\/h2>\n<p>Pretty much any generic pipe you can think of already exists. This is one project with such collection.<\/p>\n<p><a href=\"https:\/\/github.com\/danrevah\/ngx-pipes\" class=\"github\"><img decoding=\"async\" src=\"https:\/\/img.shields.io\/github\/stars\/danrevah\/ngx-pipes.svg?style=social&amp;label=Star\" \/><\/a><a href=\"https:\/\/github.com\/danrevah\/ngx-pipes\">danrevah\/ngx-pipes<\/a>:<\/p>\n<pre><code class=\"language-sh\">npm install ngx-pipes --save\n<\/code><\/pre>\n<pre><code class=\"language-typescript\">import { NgPipesModule } from 'ngx-pipes';\n\n\/\/ Each pipe is also exposed separately\n\/\/ ex: import { ReversePipe, LeftTrimPipe } from 'ngx-pipes';\n\n@NgModule({\n  imports: [NgPipesModule]\n})\n<\/code><\/pre>\n<p><strong>String:<\/strong><a href=\"https:\/\/github.com\/danrevah\/ngx-pipes\/blob\/master\/src\/ng-pipes\/pipes\/string\/shorten.ts\">shorten<\/a> , <a href=\"https:\/\/github.com\/danrevah\/ngx-pipes\/blob\/master\/src\/ng-pipes\/pipes\/string\/slugify.ts\">slugify<\/a> , <a href=\"https:\/\/github.com\/danrevah\/ngx-pipes\/blob\/master\/src\/ng-pipes\/pipes\/string\/lpad.ts\">lpad<\/a> , <a href=\"https:\/\/github.com\/danrevah\/ngx-pipes\/blob\/master\/src\/ng-pipes\/pipes\/string\/camelize.ts\">camelize<\/a><\/p>\n<p><strong>Array:<\/strong><a href=\"https:\/\/github.com\/danrevah\/ngx-pipes\/blob\/master\/src\/ng-pipes\/pipes\/array\/unique.ts\">unique<\/a> , <a href=\"https:\/\/github.com\/danrevah\/ngx-pipes\/blob\/master\/src\/ng-pipes\/pipes\/array\/tail.ts\">tail<\/a> , <a href=\"https:\/\/github.com\/danrevah\/ngx-pipes\/blob\/master\/src\/ng-pipes\/pipes\/array\/flatten.ts\">flatten<\/a> , <a href=\"https:\/\/github.com\/danrevah\/ngx-pipes\/blob\/master\/src\/ng-pipes\/pipes\/array\/every.ts\">every<\/a> , \u2026<\/p>\n<p><strong>Other:<\/strong><a href=\"https:\/\/github.com\/danrevah\/ngx-pipes\/blob\/master\/src\/ng-pipes\/pipes\/boolean\/is-greater-than.ts\">isGreaterThan<\/a> , \u2026<\/p>\n<h2 id=\"angular-pipes\">angular-pipes<\/h2>\n<p>Pretty much the same collection of pipes in this project.<\/p>\n<p><a href=\"https:\/\/github.com\/fknop\/angular-pipes\" class=\"github\"><img decoding=\"async\" src=\"https:\/\/img.shields.io\/github\/stars\/fknop\/angular-pipes.svg?style=social&amp;label=Star\" \/><\/a><a href=\"https:\/\/github.com\/fknop\/angular-pipes\">fknop\/angular-pipes<\/a>:<\/p>\n<pre><code class=\"language-sh\">npm install angular-pipes --save\n<\/code><\/pre>\n<pre><code class=\"language-typescript\">import { NgModule } from '@angular\/core';\n\nimport {\n    NgAggregatePipesModule, NgArrayPipesModule, \n    NgBooleanPipesModule, NgMathPipesModule,\n    NgObjectPipesModule, NgStringPipesModule,\n} from 'angular-pipes';\n\n\/\/ Import all pipes\n\/\/ import { NgPipesModule } from 'angular-pipes';\n\n@NgModule({\n    imports: [\n        NgArrayPipesModule,\n        NgStringPipesModule,\n    ]\n})\nexport class MyApplicationModule {}\n<\/code><\/pre>\n<p><strong>String:<\/strong><a href=\"https:\/\/github.com\/fknop\/angular-pipes\/blob\/master\/src\/string\/decode-uri.pipe.ts\">decodeURI<\/a> , <a href=\"https:\/\/github.com\/fknop\/angular-pipes\/blob\/master\/src\/string\/latinize.pipe.ts\">latinize<\/a> , <a href=\"https:\/\/github.com\/fknop\/angular-pipes\/blob\/master\/src\/string\/repeat.pipe.ts\">repeat<\/a> , <a href=\"https:\/\/github.com\/fknop\/angular-pipes\/blob\/master\/src\/string\/replace.pipe.ts\">replace<\/a> , <a href=\"https:\/\/github.com\/fknop\/angular-pipes\/blob\/master\/src\/string\/reverse-str.pipe.ts\">reverseStr<\/a> , <a href=\"https:\/\/github.com\/fknop\/angular-pipes\/blob\/master\/src\/string\/truncate.pipe.ts\">truncate<\/a> , <a href=\"https:\/\/github.com\/fknop\/angular-pipes\/blob\/master\/src\/string\/wrap.pipe.ts\">wrap<\/a> , <a href=\"https:\/\/github.com\/fknop\/angular-pipes\/blob\/master\/src\/string\/strip-tags.pipe.ts\">stripTags<\/a> , \u2026<\/p>\n<p><strong>Array:<\/strong><a href=\"https:\/\/github.com\/fknop\/angular-pipes\/blob\/master\/src\/aggregate\/max.pipe.ts\">max<\/a> , <a href=\"https:\/\/github.com\/fknop\/angular-pipes\/blob\/master\/src\/aggregate\/min.pipe.ts\">min<\/a> , <a href=\"https:\/\/github.com\/fknop\/angular-pipes\/blob\/master\/src\/aggregate\/sum.pipe.ts\">sum<\/a> , <a href=\"https:\/\/github.com\/fknop\/angular-pipes\/blob\/master\/src\/array\/count.pipe.ts\">count<\/a> , <a href=\"https:\/\/github.com\/fknop\/angular-pipes\/blob\/master\/src\/array\/head.pipe.ts\">head<\/a> , \u2026<\/p>\n<p><strong>Number \/ Math:<\/strong><a href=\"https:\/\/github.com\/fknop\/angular-pipes\/blob\/master\/src\/math\/bytes.pipe.ts\">bytes<\/a> , <a href=\"https:\/\/github.com\/fknop\/angular-pipes\/blob\/master\/src\/math\/degrees.pipe.ts\">degrees<\/a> , <a href=\"https:\/\/github.com\/fknop\/angular-pipes\/blob\/master\/src\/math\/ceil.pipe.ts\">ceil<\/a> , <a href=\"https:\/\/github.com\/fknop\/angular-pipes\/blob\/master\/src\/math\/round.pipe.ts\">round<\/a> , <a href=\"https:\/\/github.com\/fknop\/angular-pipes\/blob\/master\/src\/math\/sqrt.pipe.ts\">sqrt<\/a> , \u2026<\/p>\n<p><strong>Other:<\/strong><a href=\"https:\/\/github.com\/fknop\/angular-pipes\/blob\/master\/src\/object\/defaults.pipe.ts\">defaults<\/a> , \u2026<\/p>\n<h1>Extras<\/h1>\n<p><b>Stuff that came into being during the making of this post<\/b><\/p>\n<ul>\n<li><a href=\"https:\/\/github.com\/itenium-be\/Angular-Series\">The accompanying source on GitHub<\/a><\/li>\n<\/ul>\n<p><b>Other interesting reads<\/b><\/p>\n<ul>\n<li><a href=\"https:\/\/angular.io\/generated\/live-examples\/pipes\/stackblitz.html\">Live examples from the official docs<\/a><\/li>\n<li><a href=\"https:\/\/angular.dev\/guide\/pipes#built-in-pipes\">Official Angular Pipes docs<\/a><\/li>\n<\/ul>\n<h1>Updates<\/h1>\n<ul>\n<li> 1 June 2024: Update to Angular v18: locale configuration, i18n pipes, updated official doc links etc<\/li>\n<\/ul>\n<h1> Package Versions <i class=\"fa fa-info-circle\" style=\"float: right; color: cornflowerblue; font-size: 28px\" title=\"Package versions used for this post and in the accompanying code on Github\"><\/i><\/h1>\n<div><a href=\"https:\/\/github.com\/angular\/angular\" class=\"github\"><img decoding=\"async\" src=\"https:\/\/img.shields.io\/github\/stars\/angular\/angular.svg?style=social&#038;label=Star\" \/><\/a><a href=\"https:\/\/github.com\/angular\/angular\">angular\/angular<\/a>: v18 <\/div>\n","protected":false},"excerpt":{"rendered":"<p class=\"notice\"><strong>Pipes<\/strong>: Chainable, declarative display-value transformations to use in your Html.<\/p>\n<p>This post covers:<\/p>\n<ul>\n<li>All Builtin Angular pipes (json, async, string, array, i18n)<\/li>\n<li>How to install different locales (currency, decimal, date, percent)<\/li>\n<li>How to generate, implement and test your custom pipes<\/li>\n<li>Some examples of custom pipes (<a href=\"https:\/\/github.com\/danrevah\/ngx-pipes\">ngx-pipes<\/a> and <a href=\"https:\/\/github.com\/fknop\/angular-pipes\">angular-pipes<\/a>)<\/li>\n<\/ul>\n<p>An example:<\/p>\n<pre><code class=\"language-html\">&lt;!-- This does exactly what you'd think --&gt;\n{{ value | uppercase }}\n<\/code><\/pre>\n","protected":false},"author":1,"featured_media":2091,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[3],"tags":[23,13,6],"class_list":["post-1615","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-javascript","tag-angular","tag-cheat-sheet","tag-tutorial"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Angular Pipes - Itenium<\/title>\n<meta name=\"robots\" content=\"noindex, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Angular Pipes - Itenium\" \/>\n<meta property=\"og:description\" content=\"Pipes: Chainable, declarative display-value transformations to use in your Html.This post covers:All Builtin Angular pipes (json, async, string, array, i18n)How to install different locales (currency, decimal, date, percent)How to generate, implement and test your custom pipesSome examples of custom pipes (ngx-pipes and angular-pipes)An example: &lt;!-- This does exactly what you&#039;d think --&gt; {{ value | uppercase }}\" \/>\n<meta property=\"og:url\" content=\"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/angular-pipes\/\" \/>\n<meta property=\"og:site_name\" content=\"Itenium\" \/>\n<meta property=\"article:published_time\" content=\"2024-05-31T20:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-11-28T12:31:45+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/demo.sidekick.be\/itenium\/wp-content\/uploads\/2025\/11\/angular-pipes.png\" \/>\n\t<meta property=\"og:image:width\" content=\"360\" \/>\n\t<meta property=\"og:image:height\" content=\"300\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Usdevelop\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Usdevelop\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/angular-pipes\/\",\"url\":\"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/angular-pipes\/\",\"name\":\"Angular Pipes - Itenium\",\"isPartOf\":{\"@id\":\"https:\/\/demo.sidekick.be\/itenium\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/angular-pipes\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/angular-pipes\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/demo.sidekick.be\/itenium\/wp-content\/uploads\/2025\/11\/angular-pipes.png\",\"datePublished\":\"2024-05-31T20:00:00+00:00\",\"dateModified\":\"2025-11-28T12:31:45+00:00\",\"author\":{\"@id\":\"https:\/\/demo.sidekick.be\/itenium\/#\/schema\/person\/6ab401ce01e858184ee4a8667fe0f022\"},\"breadcrumb\":{\"@id\":\"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/angular-pipes\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/angular-pipes\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/angular-pipes\/#primaryimage\",\"url\":\"https:\/\/demo.sidekick.be\/itenium\/wp-content\/uploads\/2025\/11\/angular-pipes.png\",\"contentUrl\":\"https:\/\/demo.sidekick.be\/itenium\/wp-content\/uploads\/2025\/11\/angular-pipes.png\",\"width\":360,\"height\":300},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/angular-pipes\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/demo.sidekick.be\/itenium\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Angular Pipes\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/demo.sidekick.be\/itenium\/#website\",\"url\":\"https:\/\/demo.sidekick.be\/itenium\/\",\"name\":\"Itenium\",\"description\":\"We build software. We build careers.\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/demo.sidekick.be\/itenium\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/demo.sidekick.be\/itenium\/#\/schema\/person\/6ab401ce01e858184ee4a8667fe0f022\",\"name\":\"Usdevelop\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/demo.sidekick.be\/itenium\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/cc8cf9b9e9d5bbe7e8d247907cc9ac8457bbfa2854b52eaddf6529adfe88ceab?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/cc8cf9b9e9d5bbe7e8d247907cc9ac8457bbfa2854b52eaddf6529adfe88ceab?s=96&d=mm&r=g\",\"caption\":\"Usdevelop\"},\"sameAs\":[\"https:\/\/demo.sidekick.be\/itenium\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Angular Pipes - Itenium","robots":{"index":"noindex","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"og_locale":"en_US","og_type":"article","og_title":"Angular Pipes - Itenium","og_description":"Pipes: Chainable, declarative display-value transformations to use in your Html.This post covers:All Builtin Angular pipes (json, async, string, array, i18n)How to install different locales (currency, decimal, date, percent)How to generate, implement and test your custom pipesSome examples of custom pipes (ngx-pipes and angular-pipes)An example: &lt;!-- This does exactly what you'd think --&gt; {{ value | uppercase }}","og_url":"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/angular-pipes\/","og_site_name":"Itenium","article_published_time":"2024-05-31T20:00:00+00:00","article_modified_time":"2025-11-28T12:31:45+00:00","og_image":[{"width":360,"height":300,"url":"https:\/\/demo.sidekick.be\/itenium\/wp-content\/uploads\/2025\/11\/angular-pipes.png","type":"image\/png"}],"author":"Usdevelop","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Usdevelop","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/angular-pipes\/","url":"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/angular-pipes\/","name":"Angular Pipes - Itenium","isPartOf":{"@id":"https:\/\/demo.sidekick.be\/itenium\/#website"},"primaryImageOfPage":{"@id":"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/angular-pipes\/#primaryimage"},"image":{"@id":"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/angular-pipes\/#primaryimage"},"thumbnailUrl":"https:\/\/demo.sidekick.be\/itenium\/wp-content\/uploads\/2025\/11\/angular-pipes.png","datePublished":"2024-05-31T20:00:00+00:00","dateModified":"2025-11-28T12:31:45+00:00","author":{"@id":"https:\/\/demo.sidekick.be\/itenium\/#\/schema\/person\/6ab401ce01e858184ee4a8667fe0f022"},"breadcrumb":{"@id":"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/angular-pipes\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/angular-pipes\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/angular-pipes\/#primaryimage","url":"https:\/\/demo.sidekick.be\/itenium\/wp-content\/uploads\/2025\/11\/angular-pipes.png","contentUrl":"https:\/\/demo.sidekick.be\/itenium\/wp-content\/uploads\/2025\/11\/angular-pipes.png","width":360,"height":300},{"@type":"BreadcrumbList","@id":"https:\/\/demo.sidekick.be\/itenium\/blog\/javascript\/angular-pipes\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/demo.sidekick.be\/itenium\/"},{"@type":"ListItem","position":2,"name":"Angular Pipes"}]},{"@type":"WebSite","@id":"https:\/\/demo.sidekick.be\/itenium\/#website","url":"https:\/\/demo.sidekick.be\/itenium\/","name":"Itenium","description":"We build software. We build careers.","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/demo.sidekick.be\/itenium\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/demo.sidekick.be\/itenium\/#\/schema\/person\/6ab401ce01e858184ee4a8667fe0f022","name":"Usdevelop","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/demo.sidekick.be\/itenium\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/cc8cf9b9e9d5bbe7e8d247907cc9ac8457bbfa2854b52eaddf6529adfe88ceab?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/cc8cf9b9e9d5bbe7e8d247907cc9ac8457bbfa2854b52eaddf6529adfe88ceab?s=96&d=mm&r=g","caption":"Usdevelop"},"sameAs":["https:\/\/demo.sidekick.be\/itenium"]}]}},"_links":{"self":[{"href":"https:\/\/demo.sidekick.be\/itenium\/wp-json\/wp\/v2\/posts\/1615","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/demo.sidekick.be\/itenium\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/demo.sidekick.be\/itenium\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/demo.sidekick.be\/itenium\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/demo.sidekick.be\/itenium\/wp-json\/wp\/v2\/comments?post=1615"}],"version-history":[{"count":3,"href":"https:\/\/demo.sidekick.be\/itenium\/wp-json\/wp\/v2\/posts\/1615\/revisions"}],"predecessor-version":[{"id":2301,"href":"https:\/\/demo.sidekick.be\/itenium\/wp-json\/wp\/v2\/posts\/1615\/revisions\/2301"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/demo.sidekick.be\/itenium\/wp-json\/wp\/v2\/media\/2091"}],"wp:attachment":[{"href":"https:\/\/demo.sidekick.be\/itenium\/wp-json\/wp\/v2\/media?parent=1615"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/demo.sidekick.be\/itenium\/wp-json\/wp\/v2\/categories?post=1615"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/demo.sidekick.be\/itenium\/wp-json\/wp\/v2\/tags?post=1615"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}