RxJS operations in Angular
Angular, a popular front-end framework, helps to build responsive and scalable applications. At the core of Angular lies RxJS (Reactive Extensions for JavaScript), a powerful library for handling asynchronous operations and event-based programming. In this article, we’ll explore how RxJS helps Angular developers manage complex asynchronous tasks and streamline data flow within their applications.
Prerequisites:
Table of Content
- What are RxJS Operations?
- Uses of RxJS operations
- Common RxJS Operations in Angular
- Steps to create Angular Project
- Common RxJS operators
What are RxJS Operations?
In Angular applications, RxJS (Reactive Extensions for JavaScript) is a powerful library used for handling asynchronous and event-based programming using observables. RxJS provides a wide range of operators that enable you to manipulate, transform, combine, and manage observables in a flexible and functional way. These operators make it easier to work with data streams and asynchronous operations in a reactive manner.
Uses of RxJS operations
- Allows the users to map function to transform the value as given by the observable.
- Used to collect and combine various observables into one observable.
- Used to determine the number of values that will be emitted by the observable.
- Used to tackle or handle the error which is emitted by the observable.
- Used to filter the data on the basis of some function.
- Used to determine the time when the values will be emitted by the observables.
Common RxJS Operations in Angular
- Observable Creation:
of()
: Creates an observable that emits a sequence of values.from()
: Converts an array, promise, or iterable into an observable.ajax()
: Performs an XMLHttpRequest with the provided options and returns an observable.
- Combination Operators:
merge()
: Combines multiple observables into one by merging their emissions.combineLatest()
: Combines the latest values from multiple observables into an array or object.forkJoin()
: Combines the last values emitted by multiple observables and emits a single value when all observables complete.
- Filtering Operators:
filter()
: Emits only those values from an observable that satisfy a specified condition.distinctUntilChanged()
: Emits a value only if it is different from the previous value.debounceTime()
: Emits a value from the source observable only after a specified duration has passed without any other value being emitted.
- Transformation Operators:
map()
: Transforms each value emitted by an observable into a new value.pluck()
: Extracts the value of a specified property from each emitted object.scan()
: Applies an accumulator function to each value emitted by an observable and emits each intermediate result.
- Error Handling Operators:
catchError()
: Handles errors emitted by the source observable and returns a new observable or throws an error.retry()
: Resubscribes to the source observable a specified number of times if an error occurs.
- Utility Operators:
tap()
: Performs side effects for each emission on the source observable without modifying the emitted values.delay()
: Delays the emissions from the source observable by a specified duration.
Steps to create Angular Project
Step 1: Install Node.js and npm
We need to install Node.js and node package manager to run Angular.
Download node.js from https://nodejs.org/en/download
Step 2: Install Angular CLI
We need to install Angular command Line interface for the creation and management of our Angular projects.
To install Angular CLI, run the following command:
npm install -g @angular/cli
Step 3: Create a New Angular Project:
Now, since we have angular CLI and node.js installed on our system, now we create an Angular project
Type the following command to create a new project
ng new demo-app
Step 4: Go to the Project directory
Now, after creating the project we need to navigate down to the project directory. We can navigate into our project directory with the following command.
cd demo-app
Step 5: Run the application
Since, we have navigated to our project directory, we can run our application with the following command
ng serve
Folder Structure:
Dependencies:
"dependencies": {
"@angular/animations": "^17.3.0",
"@angular/common": "^17.3.0",
"@angular/compiler": "^17.3.0",
"@angular/core": "^17.3.0",
"@angular/forms": "^17.3.0",
"@angular/platform-browser": "^17.3.0",
"@angular/platform-browser-dynamic": "^17.3.0",
"@angular/router": "^17.3.0",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.14.3"
}
Common RxJS operators
Here’s an overview of some common RxJS operators and how they can be used in Angular:
1. map
The map operator is used to convert the values emitted by an observable into new values.. This is often used to perform some kind of data transformation.
<!-- app.component.html -->
<div>
<h1>Output Data using map operator</h1>
<ul>
<li *ngFor="let data of outputData">{{ data }}</li>
</ul>
</div>
// app.component.ts
import { Component, OnInit } from '@angular/core';
import { Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
outputData: number[] = [];
ngOnInit() {
const observable = of(1, 2, 3, 4, 5);
observable.pipe(
map(data => data * 2)
).subscribe(data => {
this.outputData.push(data);
});
}
}
Output:
2. filter
The filter operator is used to remove values from an observable depending on a criterion.
<!-- app.component.html -->
<div>
<h1>Output Data using filter operator</h1>
<ul>
<li *ngFor="let data of outputData">{{ data }}</li>
</ul>
</div>
// app.component.ts
import { Component, OnInit } from '@angular/core';
import { Observable, of } from 'rxjs';
import { filter } from 'rxjs/operators';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
outputData: number[] = [];
ngOnInit() {
const observable = of(1, 2, 3, 4, 5, 11, 13, 17, 19, 0, 5, 7);
observable.pipe(
filter(data => data > 7)
).subscribe(data => {
this.outputData.push(data);
});
}
}
Output:
3. mergeMap (flatMap)
The mergeMap operator is used to merge multiple observables into a single observable by applying a function to each emitted value and flattening the resulting observables.
<!-- app.component.html -->
<div>
<h1>Output Data using the mergeMap operator</h1>
<ul>
<li *ngFor="let data of outputData | async">{{ data }}</li>
</ul>
</div>
// app.component.ts
import { Component, OnInit } from '@angular/core';
import { Observable, of } from 'rxjs';
import { mergeMap, toArray } from 'rxjs/operators';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
outputData: Observable<number[]>;
ngOnInit() {
const observable = of(1, 2, 3, 4, 5);
const square = (data: number) => of(data * data);
this.outputData = observable.pipe(
mergeMap((data) => {
return square(data);
}),
toArray()
);
}
}
Output:
4. combineLatest
The combineLatest operator combines the latest values from multiple observables whenever any of the observables emit a new value.
<!-- app.component.html -->
<div>
<h2>combineLatest Example</h2>
<p>Latest values from observables:</p>
<ul>
<li *ngFor="let pair of combinedValues">
{{ pair[0] }} - {{ pair[1] }}
</li>
</ul>
</div>
// app.component.ts
import { Component, OnInit } from '@angular/core';
import { Observable, combineLatest, of } from 'rxjs';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
combinedValues: [number, string][] = [];
ngOnInit() {
const observable1: Observable<number> = of(1, 2, 3, 4);
const observable2: Observable<string> = of('A', 'B', 'C', 'D');
const combinedObservable: Observable<[number, string]> = combineLatest(
observable1,
observable2
);
combinedObservable.subscribe((pair) => {
this.combinedValues.push(pair);
});
}
}
Output: