Angular search pipe for a list

I'm a full-stack developer from South Africa 🇿🇦. I love writing about JavaScript, HTML and CSS.
Search for a command to run...

I'm a full-stack developer from South Africa 🇿🇦. I love writing about JavaScript, HTML and CSS.
No comments yet. Be the first to comment.
Most of you know me for my consistency, a golden arrow in my blog series. I've written 1000 articles in 1008 days! Almost an article a day, and my honeymoon was the only holiday I ever took. I'm super proud of this achievement; it has been a fantasti...

It's not the first time I'll be talking about community. I think it's an essential aspect of any successful tool. This shows in my previous explorations of Astro, Medusa, and now Vendure as well. All these products thrive in a super open, welcoming, ...

The cool part about Vendure is how easy it is to set up and how abstract each layer is. Basically, we get the following elements: External database Server Worker Admin UI Frontend While this is amazing, it also brings a bit of complexity when it co...

The previous article looked at customizing Vendure on a data and process level. In this article, we'll look at customizing emails, as they are often a big part of a webshop system. We'll be looking at two different layers of customization for customi...

Even though Vendure is a pretty significant project out of the box, in some cases, we might want to go in and modify some elements to work to our specific use case. In this article, I'll take a high-level look at some elements we can customize within...

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.

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.
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
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>
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';
And add the following line as a route.
{ path: 'list', component: ListComponent },
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'
}
];
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>
If we run this code, we should see our list rendered.

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],
})
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;
Then we modify the constructor to load the formBuilder and create the search form.
constructor(private formBuilder: FormBuilder) {
this.searchForm = this.formBuilder.group({
search: '',
});
}
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>
Note: The formControlName references the formBuilder group name.
To generate this pipe we can run the following command.
ng generate pipe SearchFilter
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>
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
}
Now, let's create the actual function.
We start by checking if the value is set.
if (value) {
// Do something
}
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');
Then we also want to get all the property's keys.
const properties = Object.keys(value[0]);
What the above does is getting the keys for the first array element.
// ['firstname', 'lastname'];
Then it's time to return an actual value.
return [
...value.filter(item => {
return properties.some(property => regexp.test(item[property]));
})
];
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.

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]));
})
];
}
}
}
You can also find this project on GitHub.
Thank you for reading my blog. Feel free to subscribe to my email newsletter and connect on Facebook or Twitter