How to Filter by Object Property in Angular

Oluwafisayo Oluwatayo Feb 02, 2024
  1. Filter By Any Object Property in Angular
  2. Filter by Specific Object Property in Angular
  3. Filter by Object Property Using Pipe in Angular
How to Filter by Object Property in Angular

The filter feature in webpages allows users to quickly narrow their searches, like in cases where you want to assess whether an item is among a long list of items. Also, we can use the filter feature where we want to filter out a list, like a list of cars.

To filter an object by its properties, you can filter the list by strings, numbers, etc. In this article, we will now look at various ways to carry out filters inside a webpage.

Filter By Any Object Property in Angular

In this example, we want to create a web app that allows us to filter with any criteria, i.e., strings and numbers. So we create a new project folder and then navigate to the index.html file to write the codes.

Code Snippet- index.html:

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Example Filter</title>
  <script src="//code.angularjs.org/snapshot/angular.min.js"></script>
</head>
<body ng-app="">
  <div ng-init="friends = [{name:'John', phone:'555-1276'},
                         {name:'Mary', phone:'800-BIG-MARY'},
                         {name:'Mike', phone:'555-4321'},
                         {name:'Adam', phone:'555-5678'},
                         {name:'Julie', phone:'555-8765'},
                         {name:'Juliette', phone:'555-5678'}]"></div>
<label>Search: <input ng-model="searchText"></label>
<table id="searchTextResults">
  <tr><th>Name</th><th>Phone</th></tr>
  <tr ng-repeat="friend in friends | filter:searchText">
    <td>{{friend.name}}</td>
    <td>{{friend.phone}}</td>
  </tr>
</table>
<hr>
</table>
</body>
</html>

It organizes the array of objects into a table, and then we are also provided with an input bar which we will use to filter the objects. We will then have to create a new file, naming it filter.js; this is where we add functionality for the app.

Code Snippet- filter.js:

var expectFriendNames = function(expectedNames, key) {
    element.all(by.repeater(key + ' in friends').column(key + '.name')).then(function(arr) {
      arr.forEach(function(wd, i) {
        expect(wd.getText()).toMatch(expectedNames[i]);
      });
    });
  };

  it('should search across all fields when filtering with a string', function() {
    var searchText = element(by.model('searchText'));
    searchText.clear();
    searchText.sendKeys('m');
    expectFriendNames(['Mary', 'Mike', 'Adam'], 'friend');

    searchText.clear();
    searchText.sendKeys('76');
    expectFriendNames(['John', 'Julie'], 'friend');
  });

So we created a function for the search input, and then we called the model inside a searchText variable. See the output below:

filter by object property in angular - filterone

Filter by Specific Object Property in Angular

This time around, we want to create an app where we can filter by a specific property, where we are to filter by string, string only works, where we are to filter by number, only number works, then we will also have search filter by anywhere we can search by both string and number.

We will do a new angular project and navigate into the index.html file to add codes that will create the page’s structure; it will include a search bar for any, by number only and by strings only.

Code Snippet- index.html:

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Example - example-filter-filter-production</title>
  <script src="//code.angularjs.org/snapshot/angular.min.js"></script>
</head>
<body ng-app="">
  <div ng-init="friends = [{name:'John', phone:'555-1276'},
                         {name:'Mary', phone:'555-2578'},
                         {name:'Mike', phone:'555-4321'},
                         {name:'Adam', phone:'555-5678'},
                         {name:'Julie', phone:'555-8765'},
                         {name:'Juliette', phone:'555-5678'}]">
    </div>
<hr>
<label>Any: <input ng-model="search.$"></label> <br>
<label>Name only <input ng-model="search.name"></label><br>
<label>Phone only <input ng-model="search.phone"></label><br>
<table id="searchObjResults">
  <tr><th>Name</th><th>Phone</th></tr>
  <tr ng-repeat="friendObj in friends | filter:search:strict">
    <td>{{friendObj.name}}</td>
    <td>{{friendObj.phone}}</td>
  </tr>
</table>
</body>
</html>

At this point, we should see the webpage with the structure defined above. Now is to design functionality for the app.

We will create a new file, name it filter.js, and then we will input these codes:

Code Snippet- filter.js:

var expectFriendNames = function(expectedNames, key) {

  it('should search in specific fields when filtering with a predicate object', function() {
    var searchAny = element(by.model('search.$'));
    searchAny.clear();
    searchAny.sendKeys('i');
    expectFriendNames(['Mary', 'Mike', 'Julie', 'Juliette'], 'friendObj');
  });
  it('should use a equal comparison when comparator is true', function() {
    var searchName = element(by.model('search.name'));
    var strict = element(by.model('strict'));
    searchName.clear();
    searchName.sendKeys('Julie');
    strict.click();
    expectFriendNames(['Julie'], 'friendObj');
  });

With the searchAny variable, we indicate that users can filter using either strings or numbers.

After we have declared the searchName variable, we also declared a strict variable, such that no data is displayed where we filter with strings in the input field for number. The same happens when we attempt to filter with the number in the input field for strings.

See the output below:

filter by object property in angular - filtertwo

Filter by Object Property Using Pipe in Angular

The pipe is ideal for running two commands or processes, which is ideal for what we are doing here. For example, we want to filter, which is one process and have it return the results of the filter, the second process.

So, we want to create a new angular project, and then we want to make a new file that will hold details of the items we want to filter. Name the file cars.ts and type in these codes:

Code Snippet- cars.ts:

export const CARS = [
    {
      brand: 'Audi',
      model: 'A4',
      year: 2018
    }, {
      brand: 'Audi',
      model: 'A5 Sportback',
      year: 2021
    }, {
      brand: 'BMW',
      model: '3 Series',
      year: 2015
    }, {
      brand: 'BMW',
      model: '4 Series',
      year: 2017
    }, {
      brand: 'Mercedes-Benz',
      model: 'C Klasse',
      year: 2016
    }
  ];

Next, we want to create a file structure that will organize the data in cars.ts into a table, including the input field for the filter. We will input the codes for that inside the app.component.html file:

Code Snippet- app.component.html

<div class="container">
  <h2 class="py-4">Cars</h2>
  <div class="form-group mb-4">
    <input class="form-control" type="text" [(ngModel)]="searchText" placeholder="Search">
  </div>
  <table class="table" *ngIf="(cars | filter: searchText).length > 0; else noResults">
    <colgroup>
      <col width="5%">
      <col width="*">
      <col width="35%">
      <col width="15%">
    </colgroup>
    <thead>
      <tr>
        <th scope="col">#</th>
        <th scope="col">Brand</th>
        <th scope="col">Model</th>
        <th scope="col">Year</th>
      </tr>
    </thead>
    <tbody>
      <tr *ngFor="let car of cars | filter: searchText; let i = index">
        <th scope="row">{{i + 1}}</th>
        <td>{{car.brand}}</td>
        <td>{{car.model}}</td>
        <td>{{car.year}}</td>
      </tr>
    </tbody>
  </table>
  <ng-template #noResults>
    <p>No results found for "{{searchText}}".</p>
  </ng-template>
</div>

Now we want to work on the functionality of the app; we will create a new file, name it filter.pipe.ts and include these codes:

Code Snippet- filter.pipe.ts

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

@Pipe({
  name: 'filter'
})
export class FilterPipe implements PipeTransform {
  transform(items: any[], searchText: string): any[] {
    if (!items) return [];
    if (!searchText) return items;

    return items.filter(item => {
      return Object.keys(item).some(key => {
        return String(item[key]).toLowerCase().includes(searchText.toLowerCase());
      });
    });
   }
}

We imported the Pipe and PipeTransform from the angular core, so when we filter the items, it transforms the data and returns the filtered results. Next, we need to access the app.component.ts file to add a bit of code for added functionality.

Code Snippet- app.component.ts:

import { Component } from '@angular/core';
import { CARS } from './cars';

interface Car {
  brand: string;
  model: string;
  year: number;
}

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'filthree';
  cars: Car[] = CARS;
  searchText: string;
}

We declared the data type for the items in the array of cars.ts. Then finally, we must import the required modules into the app.module.ts file.

Code Snippet- app.module.ts:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { FilterPipe } from './filter.pipe';

@NgModule({
  imports:      [ BrowserModule, FormsModule ],
  declarations: [ AppComponent, FilterPipe ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

We will see the following output once we are done with all the steps:

filter by object property in angular - filterthree

So, sorting items with the angular filter is one feature that makes users on your website convenient because it makes it conducive to quickly search the things you want.

Oluwafisayo Oluwatayo avatar Oluwafisayo Oluwatayo avatar

Fisayo is a tech expert and enthusiast who loves to solve problems, seek new challenges and aim to spread the knowledge of what she has learned across the globe.

LinkedIn

Related Article - Angular Filter