Angular + RxJS filter

By Arvind Rai, November 21, 2018
This page will walk through Angular RxJS filter example. RxJS filter filters values emitted by source Observable. We need to pass a predicate to filter as an argument and if predicate returns true, only when filter will emit value. The values of source Observable for which predicate returns false , will not be emitted by filter. Angular 6 integrates RxJS 6 which has been shipped with pipeable operators that is used independent of Observable. RxJS pipeable operators are used independent of Observable within the pipe method of Observable. RxJS filter is imported as following.
import { filter } from 'rxjs/operators'; 
Here we will discuss RxJS filter with examples step by step.

Technologies Used

Find the technologies being used in our example.
1. Angular 7.0.0
2. Angular CLI 7.0.3
3. TypeScript 3.1.1
4. Node.js 10.3.0
5. NPM 6.1.0
6. RxJS 6.3.3

Using RxJS filter

RxJS filter is used to filter values emitted by source Observable on the basis of given predicate. If the condition returns true, filter will emit value obtained from source Observable otherwise not. Find the some usability of RxJS filter operator.
1. Filter value on the basis of given character.
this.stdNames$ = this.filterDemoService.getStdNames().pipe(
  filter(data => data.indexOf(",") > 0),
  map(res => res.split(","))
); 
In the above code, if value emitted by Observable returned by getStdNames() has no (",") character, then it will not pass source Observable to map operator.
2. Filter numbers on the basis of odd/even.
this.filterDemoService.getNumbers().pipe(
  tap(n => console.log(n)),
  filter(n => n % 2 === 0),
  map(n => n + 10),
  scan((sum, n) => sum + n)
)
.subscribe(result => console.log(result)); 
3. Filter values for null.
this.countryName$ = this.filterDemoService.getCountry().pipe(
  filter(country => country.getCountryName() !== null),
  map(country => country.getCountryName()),
  catchError(err => {
	console.error(err);
	return of("");
  })
); 

Error Handling and RxJS filter

RxJS provides retry and catchError operators for error handling in Angular. We can use catchError with filter and if there is any error in filter, it will be handled by catchError. Find the sample example of filter with error handling.
this.filterDemoService.getCountry().pipe(
  retry(2),
  filter(country => country.getCountryStates().length > 0),
  map(country => country.getCountryStates()),
  catchError(err => {
	console.error(err);
	return of([]);
  })
)
.subscribe(res => this.countryStates = res); 

JavaScript Array filter vs RxJS filter

JavaScript Array filter works on element of JavaScript Array and RxJS filter is the RxJS operator that works on element emitted by Observable.
a. JavaScript Array filter filters the array by applying given predicate to each element of the array and the element for which predicate returns true, will remain in output array.
Suppose we have an array as following.
let numArray = [1, 2, 3, 4];
Find the sample example of JavaScript Array filter.
numArray.filter(n => {
 console.log(n);
 return n % 2 === 0;
})
.forEach(el => console.log("Even Number: " +el)); 
Find the output.
1 
2 
3 
4
Even Number: 2 
Even Number: 4 
b. RxJS filter filters the values emitted by Observable. Find the code to use RxJS filter.
of(numArray).pipe(
 filter(dataArray => { 
   console.log(dataArray);
   return dataArray.length > 0;
 })
).subscribe(resArray => console.log(resArray.join(" | "))); 
Find the output.
Array(4) [ 1, 2, 3, 4 ]
1 | 2 | 3 | 4 

Complete Example

filter-demo.component.ts
import { Component, OnInit } from '@angular/core';
import { Observable, of } from 'rxjs';
import { map, tap, filter, scan, retry, catchError } from 'rxjs/operators';
import { FilterDemoService } from './filter-demo.service';

@Component({
   selector: 'app-filter-demo',
   templateUrl: './filter-demo.component.html'
})
export class FilterDemoComponent implements OnInit { 
   stdNames$: Observable<string[]>; 
   countryName$: Observable<string>;
   countryStates: string[];

   constructor(private filterDemoService: FilterDemoService) { }
   
   ngOnInit() {
      this.getStdNames();
      this.calcData();      
      this.getCountryName();
      this.getCountryStates();

      let numArray = [1, 2, 3, 4];

      //Using JavaScript Array filter
      numArray.filter(n => {
         console.log(n);
         return n % 2 === 0;
       })
      .forEach(el => console.log("Even Number: " +el));
  
      //Using RxJS filter
      of(numArray).pipe(
        filter(dataArray => { 
          console.log(dataArray);
          return dataArray.length > 0;
        })
      ).subscribe(resArray => console.log(resArray.join(" | "))); 

      
   }

   //Using filter and map 
   getStdNames() {
    this.stdNames$ = this.filterDemoService.getStdNames().pipe(
      filter(data => data.indexOf(",") > 0),
      map(res => res.split(","))
    );
   }	

   //Using tap, filter, map and scan
   calcData() {
    this.filterDemoService.getNumbers().pipe(
      tap(n => console.log(n)),
      filter(n => n % 2 === 0),
      map(n => n + 10),
      scan((sum, n) => sum + n)
    )
    .subscribe(result => console.log(result));
   }

   //Using filter, map and catchError
   getCountryName() {
    this.countryName$ = this.filterDemoService.getCountry().pipe(
      filter(country => country.getCountryName() !== null),
      map(country => country.getCountryName()),
      catchError(err => {
        console.error(err);
        return of("");
      })
    );
   }

   //Using retry, map and catchError
   getCountryStates() {
    this.filterDemoService.getCountry().pipe(
      retry(2),
      filter(country => country.getCountryStates().length > 0),
      map(country => country.getCountryStates()),
      catchError(err => {
        console.error(err);
        return of([]);
      })
    )
    .subscribe(res => this.countryStates = res); 
   }
} 
filter-demo.component.html
<b>Student Names</b>
<ul>
  <li *ngFor="let name of stdNames$ | async" >
    {{name}}
  </li>
</ul>

<b>Country Name</b>
<div *ngIf="countryName$ | async as myCountryName">
  {{myCountryName}} 
</div>

<b>Country States</b>
<ul>
  <li *ngFor="let state of countryStates" >
    {{state}}
  </li>
</ul> 
filter-demo.service.ts
import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
import { MyCountry } from './my-country';

@Injectable({
    providedIn: 'root'
})
export class FilterDemoService {
    getNumbers(): Observable<number> {
      return of(1, 2, 3, 4); //Synchronously emits 1, 2, 3, 4 and then completes
    }
    getStdNames(): Observable<string> {
      return of("Mahesh, Krishna, Ram");
    }	
    getCountry(): Observable<MyCountry> {
      return of(new MyCountry());
    }
} 
my-country.ts
export class MyCountry {
   getCountryName() {
       return "India";
   }  
   getCountryStates() {
       return ["UP", "MP", "Assam", "Kerla"];
   }
} 
app.component.ts
import { Component } from '@angular/core';

@Component({
   selector: 'app-root',
   template: `
	<app-filter-demo></app-filter-demo>
    `
})
export class AppComponent { 
} 
app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';

import { AppComponent }  from './app.component';
import { FilterDemoComponent }  from './filter-demo.component';
import { FilterDemoService } from './filter-demo.service';

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

Run Application

To run the application, find the steps.
1. Download source code using download link given below on this page.
2. Use downloaded src in your Angular CLI application. To install Angular CLI, find the link.
3. Run ng serve using command prompt.
4. Access the URL http://localhost:4200
Find the print screen of the output.
Angular + RxJS filter

References

RxJS Observable
Angular: The RxJS library
Pipeable Operators

Download Source Code

POSTED BY
ARVIND RAI
ARVIND RAI









©2023 concretepage.com | Privacy Policy | Contact Us