Creating And Using Custom Pipes In An Angular Web Application

When I’m developing with Angular, I often find myself needing to loop over an object via HTML markup. In AngularJS one could loop over object properties or arrays, but in Angular you can only loop over arrays by default. This is easily fixable through what are known as Angular Pipes.

With pipes you can create display-value transformations for pretty much anything, or in my case transform an object into an array and loop over it. We’re going to see how to create a pipe that will allow us to loop over an object in the HTML layer.

The concepts and most of the code that is discussed here can be used in Angular web applications or mobile applications built with NativeScript or Ionic Framework. Our focus will be on the web, but it shouldn’t really make a difference.

For simplicity, let’s create a fresh project to work with. Using the Angular CLI, assuming you’ve installed it, execute the following command:

ng new MyProject

With the project created, we need to create a new pipe. We can actually use the CLI to create pipes which is a huge convenience for us as a developer. Using the Angular CLI, execute the following

ng g pipe keys

With the pipe created, let’s start adding some code. The goal here will be to take an object, and return an array of its properties so that way we can loop over the properties via HTML markup.

Open the project’s src/app/keys.pipe.ts file and include the following TypeScript code:

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

@Pipe({
    name: 'keys'
})
export class KeysPipe implements PipeTransform {

    public transform(value: any, args?: any): any {
        let keys = [];
        for (let key in value) {
            keys.push({key: key, value: value[key]});
        }
        return keys;
    }

}

The transform function is part of the PipeTransform implementation. It is called when we try to use the pipe in our HTML. Like previously mentioned, we will loop through each top level property of the object and create an array of the properties. This array will be an array of objects that represent a key-value pair.

Before the pipe can be used, it must be added to the project’s @NgModule block. Open the project’s src/app/keys.pipe.ts file and include the following TypeScript code:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';

import { AppComponent } from './app.component';
import { KeysPipe } from './keys.pipe';

@NgModule({
    declarations: [
        AppComponent,
        KeysPipe
    ],
    imports: [
        BrowserModule,
        FormsModule,
        HttpModule
    ],
    providers: [],
    bootstrap: [AppComponent]
})
export class AppModule { }

Notice in the above code that the pipe was imported and added to the declarations section of the @NgModule block.

Now we can make use of the pipe, but before we do, we need to create an object via some TypeScript. To keep this application simple we won’t be creating any new pages, but instead use what the Angular CLI had already provided us.

Open the project’s src/app/app.component.ts file and include the following TypeScript code:

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

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent {

    public info: any;

    public constructor() {
        this.info = {
            "firstname": "Nic",
            "lastname": "Raboy",
            "urls": [
                "https://www.thepolyglotdeveloper.com",
                "https://www.twitter.com/nraboy"
            ]
        }
    }

}

What we’re focusing on in the above is the info object that will be available in the HTML. This object has a few properties, one of which is an array. We want to loop over this object, not necessarily the array that exists inside it.

Open the project’s src/app/app.component.html file and include the following HTML markup:

<div *ngFor="let i of info | keys">
    <p *ngIf="i.key != 'urls'">{{ i.key }}: {{ i.value }}</p>
    <div *ngIf="i.key == 'urls'">
        <p>urls:</p>
        <ul>
            <li *ngFor="let url of i.value">
                {{ url }}
            </li>
        </ul>
    </div>
</div>

The above HTML has a few things going on. The first loop will take the info object and pipe it into our transformation which will return an array of property names and values. If the property name is not urls then print out the key and value, otherwise we’re going to create a second loop to print out each available URL.

Again, the emphasis here is on the pipe transformation which can really be whatever you want. This is just an example that I’ve used in a few applications. It is useful if you have a dynamic object that you wish to display on the screen.

Conclusion

You just saw how to create a custom pipe in Angular. In this particular example we created a pipe that transforms an object and returns an array of property names so that we can loop through them in the HTML markup. Other useful pipes might include formatting of phone numbers, or any other manipulation that needs to happen to data before presenting it on the screen.

A video version of this article can be found below.

Nic Raboy

Nic Raboy

Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in Java, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Apache Cordova. Nic writes about his development experiences related to making web and mobile development easier to understand.

Search

Follow Us

Subscribe

Subscribe to my newsletter for monthly tips and tricks on subjects such as mobile, web, and game development.

Subscribe on YouTube

Support This Site