Skip to content
Angular2: filtering ngFor using pipes

Angular2: filtering ngFor using pipes

Angular2 / Bootstrap4 table

I'm still working on a Stripe administration console for OctoPerf, a SaaS performance testing tool. Stripe lets us manage our customers and their subscriptions.

I have a table that lists all of our customers (Customers.html):

<table class="table table-striped">
  <thead class="thead-default">
  <tr>
    <th>#</th>
    <th>Id</th>
    <th>Email</th>
  </tr>
  </thead>
  <tbody>
  <tr *ngFor="#customer of customers; #i = index">
    <th scope="row">{{i}}</th>
    <td>{{customer.id}}</td>
    <td>{{customer.email}}</td>
  </tr>
  </tbody>
</table>

It's an Angular2 application build using this excellent starter with BootStrap 4.

Elevate your Load Testing!
Request a Demo

Filtering the content using a Pipe

Our goal is to filter the customers by their email. The first step is to create a PipeTransform implementation:

import {Injectable, Pipe, PipeTransform} from 'angular2/core';
import {Customer} from '../services/Customer';

@Pipe({
  name: 'customerEmailFilter'
})
@Injectable()
export class CustomerEmailFilter implements PipeTransform {
  transform(customers: Customer[], args: any[]): any {
    return customers.filter(customer => customer.email.toLowerCase().indexOf(args[0].toLowerCase()) !== -1);
  }
}

It's pretty much like the AngularJS filters. The transform method takes a customers array and some args as parameters and filters the array depending on the arg value.

Note:

We don't have to set a type like customers: Customer[] to the transformed list. We could also create a more generic filter using an object array: items: any[].

Using the Pipe in our table component

To use the email filter in our Customers table component we must declare it in the annotation:

import {Component} from 'angular2/core';

import {StripeClient} from '../services/StripeClient';
import {Customer} from '../services/Customer';
import {CustomerEmailFilter} from './CustomerEmailFilter';

@Component({
  selector: 'customers',
  pipes: [CustomerEmailFilter],
  providers: [],
  directives: [],
  styles: [require('./Customers.css')],
  template: require('./Customers.html'),
})
export class Customers {
  private customers: Customer[];
  private email: string = '';

  constructor(private client: StripeClient) {
    this.customers = [];
  }

  ngOnInit() {
    this.client.getCustomers((customers: Customer[]) => {
      this.customers = customers;
    });
  }
}

The pipes: [CustomerEmailFilter], line allows us to use customerEmailFilter in the Customers.html file. We also declare a field email that holds the value for the filter argument.

The resulting html file has an input text in the table header. It allows the user to set the filter value: [(ngModel)]="email".

<table class="table table-striped">
  <thead class="thead-default">
  <tr>
    <th>#</th>
    <th>Id</th>
    <th><input type="text" id="inputEmail" class="form-control" placeholder="Email" [(ngModel)]="email"></th>
  </tr>
  </thead>
  <tbody>
  <tr *ngFor="#customer of customers | customerEmailFilter:email; #i = index">
    <th scope="row">{{i}}</th>
    <td>{{customer.id}}</td>
    <td>{{customer.email}}</td>
  </tr>
  </tbody>
</table>

And the ngFor is now filtered: *ngFor="#customer of customers | customerEmailFilter:email.

Notes:

  • customerEmailFilter is the name of the CustomerEmailFilter declared in the @Pipe annotation.
  • :email refers to the email field of the Customer component.

The resulting table:

Angular2 filtered table using pipes

Want to become a super load tester?
Request a Demo