Pada modul ini kita akan bahas pure dan impure pipe.
Kita akan buat pipe untuk melakukan filter, skenarionya akan me-filter list berdasarkan status server.
Buat pipe baru dengan nama filter. Kita gunakan CLI.
Perhatian: karena menggunakan CLI, registrasi pada app.module.ts sudah otomatis dilakukan oleh Angular.
$ ng g p filter --skip-tests
Buka file fiter.pipe.ts, tambahkan code berikut:
Pipe filter akan melakukan filtering berdasarkan paramater
- filterStr: status yang akan ditampilkan.
- propName: property yang akan difilter.
import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'filter' }) export class FilterPipe implements PipeTransform { transform(value: any, filterStr: string, propName: string): any { if (value.length===0){ return value; } const resultArray = []; for (const item of value){ if (item[propName]===filterStr){ resultArray.push(item); } } return resultArray; } }
Untuk keperluan ini, kita modifikasi sedikit pada file app.component.html
- Tambahkan input type text untuk tempat memasukan filter string.
- Tambankan button untuk menambahkan new server.
- Lakukan pipe pada *ngFor.
<div class="container"> <div class="row"> <div class="col-xs-12 col-sm-10 col-md-8 col-sm-offset-1 col-md-offset-2"> <input type="text" [(ngModel)]="filteredStat"> <br><br> <button class="btn btn-primary" (click)="onAddServ()">Add Server</button> <hr> <ul class="list-group"> <li class="list-group-item" *ngFor="let server of servers | filter:filteredStat:'status'" [ngClass]="getStatusClasses(server)"> <!-- gunakan custom pipe disini --> <strong>{{ server.name | shorten:5 }}</strong> | {{ server.instanceType | uppercase }} | {{ server.started | date:'fullDate' | uppercase }} <span class="badge bg-dark"> {{ server.status }} </span> </li> </ul> </div> </div> </div>
buka file app.component.ts, lalu tambahkan perubahan:
- property untuk menyimpan data string filter
- method untuk handling button click
import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { servers = [ { instanceType: 'medium', name: 'Production Server', status: 'stable', started: new Date(15, 3, 2022) }, { instanceType: 'large', name: 'Order Database', status: 'stable', started: new Date(15, 3, 2022) }, { instanceType: 'small', name: 'Development Server', status: 'offline', started: new Date(15, 3, 2022) }, { instanceType: 'small', name: 'Testing Blockchain Server', status: 'stable', started: new Date(15, 3, 2022) } ]; //tambahkan property filterStat filteredStat = ''; getStatusClasses(server: {instanceType: string, name: string, status: string, started: Date}) { return { 'list-group-item-success': server.status === 'stable', 'list-group-item-warning': server.status === 'offline', 'list-group-item-danger': server.status === 'critical' }; } //method untuk handling button Add Server onAddServ(){ this.servers.push( { instanceType: 'small', name: 'New Server', status: 'stable', started: new Date(15, 3, 2022) } ); } }
Sekarang lakukan testing berikut, masukan string filter. Misalnya stable atau offline. Dapat Anda lihat, list server stable atau offline saja.

Sesuai ekspektasi, filter berfungsi dengan baik.
Pure dan Impure Pipe
Sekarang masukan filter string stable, kemudian tekan tombol button Add server (button ini akan menambahkan data server dengan status stable).
Dapat Anda lihat, data yang sudah terfilter tidak akan otomatis ditampilkan.
Hal ini terjadi karena kita membuat pure filter. Artinya filter tidak akan di execute ketika terjadi perubahan pada Objects atau Arrays.
Jika Anda hapus string filter, kemudian ketik ulang status stable, hasil filter akan menampilkan server yang baru ditambahkan.

Hal ini memang behaviour dari Angular dengan tujuan menjaga performa dari aplikasi. Dapat dibayangkan jika filter selalu di execute ketika terjadi perubahan data, maka dapat menimbulkan masalah performa.
Jika Anda yakin, bahwa pipe yang Anda buat perlu di eksekusi ulang, Anda dapat definisikan sebagai impure pipe pada decorator @Pipe.
Buka file filter.pipe.ts, lalu tambahkan property pure seperti code dibawah.
import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'filter', pure: false //property untuk mengubah pipe menjadi impure. }) export class FilterPipe implements PipeTransform { transform(value: any, filterStr: string, propName: string): any { if (value.length===0){ return value; } const resultArray = []; for (const item of value){ if (item[propName]===filterStr){ resultArray.push(item); } } return resultArray; } }
Lakukan testing lagi dengan memasukan filter string stable, kemudian tekan button Add Server. Kali ini server baru yang ditambahkan akan langsung ditampilkan.