Creating a custom pipe

Pipes are also a feature of Angular 2 and are not specific to Ionic. If you are familiar with Angular 1, a pipe is exactly the same thing as a filter. The main reason you might want to use pipes is to display data in a different format in the view. You don't want to change the actual value in the component. This makes things very convenient because you don't have to decide on the specific format within the code, while leaving flexibility in the view layer. Here is a list of some useful built-in pipes (from https://angular.io/docs/ts/latest/api/#!?apiFilter=pipe):

  • AsyncPipe
  • DatePipe
  • NumberPipe
  • SlicePipe
  • DecimalPipe
  • JsonPipe
  • PercentPipe
  • UpperCasePipe
  • LowerCasePipe
  • CurrencyPipe
  • ReplacePipe

In this section, you will learn how to create a custom pipe using the @Pipe decorator. The following is a screenshot of the app:

Creating a custom pipe

While the app interface is very simple, this example is to show you how to create a pipe to extract object data.

Getting ready

There is no need to test in a physical device because the Angular 2 pipe will work just fine in the web browser.

How to do it...

Observe the following instructions:

  1. Create a new CustomPipe app using the blank template, as shown, and go to the CustomPipe folder:
    $ ionic start CustomPipe blank --v2
    $ cd CustomPipe
    
  2. Open the ./src/pages/home/home.html file and modify the content with the following code:
    <ion-header>
      <ion-navbar>
        <ion-title>
          User
        </ion-title>
      </ion-navbar>
    </ion-header>
    
    <ion-content padding>
    
      <h4>Unformatted Value</h4>
      <ion-card>
    
        <ion-card-header>
          <code>user</code>
        </ion-card-header>
    
        <ion-card-content>
          {{ user | json }}
        </ion-card-content>
    
      </ion-card>
      
      <h4>Formatted Value</h4>
      <ion-list>
    
        <ion-item>
          <ion-label fixed>First Name</ion-label>
          <ion-note item-right>{{ user | userExtract : "firstname" }}</ion-note>
        </ion-item>
    
        <ion-item>
          <ion-label fixed>Last Name</ion-label>
          <ion-note item-right>{{ user | userExtract : "lastname" }}</ion-note>
        </ion-item>
        
        <ion-item>
          <ion-label fixed>Age</ion-label>
          <ion-note item-right>{{ user | userExtract : "age" }}</ion-note>
        </ion-item>
    
      </ion-list>
    </ion-content>

    You can quickly see that the template uses the userExtract pipe to render the correct information.

  3. Then, replace the content of ./src/pages/home/home.ts with the following code:
    import { Component } from '@angular/core';
    import { NavController } from 'ionic-angular';
    
    @Component({
      selector: 'page-home',
      templateUrl: 'home.html'
    })
    export class HomePage {
      private user: any;
      
      constructor(public navCtrl: NavController) {
        this.user = {
          name: 'John Connor',
          birthyear: 1985
        }
      }
    
    }

    You don't have the custom-pipe.ts file yet, so, you need to create it next.

  4. Create the ./src/utils folder by using the following command:
    $ mkdir ./src/utils
    

    You can call this folder anything. However, since, sometimes, pipes are considered utility functions, let's call it utils.

  5. Create the custom-pipe.ts file in the utils folder and copy the following code:
    import { Pipe, PipeTransform } from '@angular/core';
    
    @Pipe({name: 'userExtract'})
    export class UserExtractPipe implements PipeTransform {
      transform(value: any, arg) : any {
        let newVal: any;
        if (arg == "firstname") {
          
          newVal = value.name ? value.name.split(' ')[0] : '';
    
        } else if (arg == "lastname") {
          
          newVal = value.name ? value.name.split(' ').splice(-1) : '';
          
        } else if (arg == "age") {
          var currentTime = new Date();
          
          newVal = value.birthyear ? currentTime.getFullYear() - value.birthyear : 0;
        }
        
        return newVal;
      }
    }
  6. Add UserExtractPipe to ./src/app/app.module.ts by replacing with the following code:
    import { NgModule } from '@angular/core';
    import { IonicApp, IonicModule } from 'ionic-angular';
    import { MyApp } from './app.component';
    import { HomePage } from '../pages/home/home';
    import { UserExtractPipe } from '../utils/custom-pipe'
    
    @NgModule({
      declarations: [
        MyApp,
        HomePage,
        UserExtractPipe
      ],
      imports: [
        IonicModule.forRoot(MyApp)
      ],
      bootstrap: [IonicApp],
      entryComponents: [
        MyApp,
        HomePage
      ],
      providers: []
    })
    export class AppModule {}
  7. Go to your terminal and run the app, as follows:
    $ ionic serve
    

How it works…

You can use an Angular 2 pipe in the view to simply convert or transform any value to a desired value. There is no limitation on how you want to structure the pipe. Angular 2 automatically detects the | sign in the template and turns the value in front of it to an input. To create a pipe, you must import the decorator and provide a name (see custom-pipe.ts), as shown:

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

@Pipe({name: 'userExtract'})

The input from the template is the following value parameter:

transform(value: any, arg) : any {

The value returned by the transform method will be the output to the view, as shown in the following code:

return newVal;

In this example, you are taking a parameter for the pipe to process, as illustrated in the following code:

    if (arg == "firstname") {
      
      newVal = value.name ? value.name.split(' ')[0] : '';

    } else if (arg == "lastname") {
      
      newVal = value.name ? value.name.split(' ').splice(-1) : '';
      
    } else if (arg == "age") {
      var currentTime = new Date();
      
      newVal = value.birthyear ? currentTime.getFullYear() - value.birthyear : 0;
    }

For example, this is what you had in the home.html template:

    <ion-item>
      <ion-label fixed>First Name</ion-label>
      <ion-note item-right>{{ user | userExtract : "firstname" }}</ion-note>
    </ion-item>

Each parameter is placed after a colon (:). Then, within your @Pipe class, you can refer to it using arg. The rest of the code is very simple as already shown in the preceding section. Observe the following

  • If it's firstname, take the first word after splitting by space
  • If it's lastname, take the last word
  • If it's age, subtract the current year from birth year

Of course, you could have more complicated scenarios with pipes. However, the overall recommendation is to keep things simple at the view to ensure rendering performance. If you need to do heavy processing, it's best to handle it as a separate variable.

See also

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.138.134