DEV Community

Cover image for Angular search pipe for a list
Chris Bongers
Chris Bongers

Posted on • Originally published at daily-dev-tips.com

Angular search pipe for a list

In today's article, we'll be creating a live-search function for an Angular list.

With this, I plan to have a list rendered in Angular and an input type above it. If we type in this input we should see the list contents change.

You can see the end result in this GIF.

Angular search pipe for a list

Setting up the project

For this project, we will be using my master Angular project, since we don't want to setup Angular from Scratch.

Note: Check out this article if you plan to install Angular from scratch

Download the starter project or install it yourself, then you can open your terminal and run ng serve.

Creating the list

The next part is to create a new component, this is the List component.
We can use the Angular generator to create this component for us.

ng generate component list
Enter fullscreen mode Exit fullscreen mode

You can then add this list component to your app.component.html file.

<li><a routerLink="/welcome" routerLinkActive="active">Welcome</a></li>
<li><a routerLink="/list" routerLinkActive="active">List</a></li>
Enter fullscreen mode Exit fullscreen mode

Then we need to active the route in our routing file.
Open up the app-routing.module.ts.

You'll need to import the Component on the top.

import {ListComponent} from './list/list.component';
Enter fullscreen mode Exit fullscreen mode

And add the following line as a route.

{ path: 'list', component: ListComponent },
Enter fullscreen mode Exit fullscreen mode

Now we should be able to run our application and visit the /list route.

The next thing we want to add is our data, so open up the list.component.ts file and add the following data set.

people = [
  {
    firstname: 'Chris',
    lastname: 'Bongers'
  },
  {
    firstname: 'Peter',
    lastname: 'Rabbit'
  },
  {
    firstname: 'Donald',
    lastname: 'Duck'
  },
  {
    firstname: 'Lady',
    lastname: 'Gaga'
  }
];
Enter fullscreen mode Exit fullscreen mode

We want to show this list on the HTML side, so we need to render it in our HTML file.

<ul>
  <li *ngFor="let person of people">
    {{ person.firstname }} {{ person.lastname }}
  </li>
</ul>
Enter fullscreen mode Exit fullscreen mode

If we run this code, we should see our list rendered.

Angular rendered list

As mentioned we need to have a search input on top of this list, this needs to be connected to a model so we can use the value.

First, we need to enable the ReactiveForms module.

We can add it in our app.module.ts file.

// Other imports
import { ReactiveFormsModule } from '@angular/forms';

@NgModule({
  declarations: [...],
  imports: [ReactiveFormsModule, ...],
  providers: [],
  bootstrap: [AppComponent],
})
Enter fullscreen mode Exit fullscreen mode

With this in place, we can go ahead and create the form in our list.component.ts.

The first thing we add is a variable for our searchForm.

searchForm;
Enter fullscreen mode Exit fullscreen mode

Then we modify the constructor to load the formBuilder and create the search form.

constructor(private formBuilder: FormBuilder) {
    this.searchForm = this.formBuilder.group({
      search: '',
    });
}
Enter fullscreen mode Exit fullscreen mode

This will create a form we can use in our HTML file.

Add the following form on top of our list.

<form [formGroup]="searchForm">
  <input formControlName="search" />
</form>
Enter fullscreen mode Exit fullscreen mode

Note: The formControlName references the formBuilder group name.

Generating the Angular Search Pipe

To generate this pipe we can run the following command.

ng generate pipe SearchFilter
Enter fullscreen mode Exit fullscreen mode

This will generate and register our pipe for us.

To use this pipe we need to add it to the ngFor on the list we created in list.component.ts.

<li *ngFor="let person of people | searchFilter: searchForm.value.search"></li>
Enter fullscreen mode Exit fullscreen mode

As you can see above we add the searchFilter pipe and pass the argument of the search field value.

Now we need to make sure this searchFilter pipe will return only matching results.

Let's create the outline for this filter first.
Our filter has 2 parameters, one being the input (value) and one being the search (string).

We use typescript to define what our value looks like, in this case, it's an array with an object in it.

Then you'll see the : which defines the output for this transform function.

transform(
    value: { firstname: string; lastname: string }[],
    search: string
): { firstname: string; lastname: string }[] {
    //return something
}
Enter fullscreen mode Exit fullscreen mode

Now, let's create the actual function.

We start by checking if the value is set.

if (value) {
  // Do something
}
Enter fullscreen mode Exit fullscreen mode

If we do get a value, we need to create a regular expression to match against based on the search parameter.

const regexp = new RegExp(search, 'i');
Enter fullscreen mode Exit fullscreen mode

Then we also want to get all the property's keys.

const properties = Object.keys(value[0]);
Enter fullscreen mode Exit fullscreen mode

What the above does is getting the keys for the first array element.

// ['firstname', 'lastname'];
Enter fullscreen mode Exit fullscreen mode

Then it's time to return an actual value.

return [
  ...value.filter(item => {
    return properties.some(property => regexp.test(item[property]));
  })
];
Enter fullscreen mode Exit fullscreen mode

This is a bit of a tricky one, we return an array [].
Inside this array, we use the spread operator to get a copy of the value array.

We use the JavaScript filter method to filter the values.
Inside the filter, we return a boolean, because we use the JavaScript some method on the property array.

To demo this out what will happen if we search for chris.

We'll get in the loop, and we ask if one of the properties (firstname/lastname) matches the regular expression based on the search string.

In the first case, this is true, so the result will be returned as yes, in the other ones it's false.

The end result is an array of 1 object, being Chris Bongers.

Angular search list result

The full search pipe will look as follows.

import {Pipe, PipeTransform} from '@angular/core';
@Pipe({
  name: 'searchFilter'
})
export class SearchFilterPipe implements PipeTransform {
  transform(
    value: {firstname: string, lastname: string}[],
    search: string
  ): {firstname: string, lastname: string}[] {
    if (value) {
      const regexp = new RegExp(search, 'i');
      const properties = Object.keys(value[0]);
      return [
        ...value.filter(item => {
          return properties.some(property => regexp.test(item[property]));
        })
      ];
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

You can also find this project on GitHub.

Thank you for reading, and let's connect!

Thank you for reading my blog. Feel free to subscribe to my email newsletter and connect on Facebook or Twitter

Top comments (2)

Collapse
 
iamsunil25 profile image
Sunil joshi

you explained very well

Collapse
 
dailydevtips1 profile image
Chris Bongers

Thank you Sunil, glad you liked the article 🤟