Creating a simple custom pipe in Angular

in #angular6 years ago

What are you even talking about?

When you retrieve data from a server, it's often not exactly in the format that you want to display it to your users.

Changing the format of the data directly on the server is in most cases not a very good idea or, if you don't have any control over the server-side code, impossible.

The solution is to make a pipe to manipulate our data and show it in the correct format to our user. In this post, I will create a simple pipe that will capitalize the first letter of a word or sentence.

The capitalize pipe

Our capitalize pipe will transform an input string and capitalize the first letter of each word.

When creating a pipe it is important to use the Pipe decorator and implement the PipeTransform interface. This provides us with a function in which we can transform our data.

capitalize.pipe.ts

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({name: 'capitalize'})
export class CapitalizePipe implements PipeTransform{

    transform(value: any, args: string[]):any {
        if (!value){
            return value;
        }

        return value.replace(/\b\w/g, function(txt) {
          return txt.charAt(0)
            .toUpperCase() +
            txt.substr(1)
              .toLowerCase();
        });
    }
}


Pure - Impure


Important to note here is the optional parameter for our pipe decorator. Optionally, we could indicate that our pipe is not pure in our Pipe annotation
Pipe({name:'capitalize', pure:false})

A pure pipe does not have state and the output of the function will only change when there is a different input. Because of this, change detection will only happen when the input value changes. This also means that Angular can use the same pipe in multiple places, and only one instance will be created.

However, when you pass an object that has state to an impure pipe, Angular will create an instance every time you use the pipe. Change detection will happen more often, as there can be a different output if the state changes. This can considerably decrease performance if not used carefully, so think before you act people.

As our little example only takes an input string, we can leave the default and use a pure pipe.

app component


To be able to use our pipe, we have to declare it in our module, so let us change the app module.

app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { CapitalizePipe } from './capitalize.pipe';
import { AppComponent } from './app.component';
import { HelloComponent } from './hello.component';

@NgModule({
  imports:      [ BrowserModule, FormsModule ],
  declarations: [ AppComponent, HelloComponent, CapitalizePipe ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }


That did it!

All that is left to do now is to test it in our app component and use the pipe in our template.

app.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `<h1>{{ name | capitalize}}</h1>`
})
export class AppComponent  {
  name = 'john doe';
}



Result


As you can see in the result, our name got capitalized. Of course, this is a very simple pipe, but I hope you can see how easy it is to manipulate your data to show it to your users in the format you want.

You can find a working example on StackBlitz here