Introduction
RxJS (Reactive Extensions for JavaScript) is a library for reactive programming using Observables, which are a powerful way to manage asynchronous and event-driven code. In Angular, RxJS is commonly used for handling asynchronous operations, such as HTTP requests and user input.
Here are some commonly used RxJS operators in Angular:
map
Transforms the items emitted by an Observable by applying a function to each item.
import { map } from 'rxjs/operators';
// Example:
observable.pipe(
  map(data => data * 2)
);
filter
Emits only those items from an Observable that pass a specified condition.
import { filter } from 'rxjs/operators';
// Example:
observable.pipe(
  filter(data => data > 5)
);
tap (do)
Perform a side effect for every emission on the source Observable, but return an Observable that is identical to the source.
import { tap } from 'rxjs/operators';
// Example:
observable.pipe(
  tap(data => console.log(data))
);
switchMap
Projects each source value to an Observable, flattens the emissions into a single Observable.
import { switchMap } from 'rxjs/operators';
// Example:
observable.pipe(
  switchMap(data => newObservable)
);
mergeMap (flatMap)
Maps each value to an Observable and then flattens all of these inner Observables.
import { mergeMap } from 'rxjs/operators';
// Example:
observable.pipe(
  mergeMap(data => newObservable)
);
catchError (catch)
Catches errors on the observable and replaces the error with another observable.
import { catchError } from 'rxjs/operators';
// Example:
observable.pipe(
  catchError(error => handleError)
);
debounceTime
Emits a value from the source Observable only after a specified time period has passed without another source emission.
import { debounceTime } from 'rxjs/operators';
// Example:
observable.pipe(
  debounceTime(300)
);
distinctUntilChanged
Only emits when the current value is different from the previous one.
import { distinctUntilChanged } from 'rxjs/operators';
// Example:
observable.pipe(
  distinctUntilChanged()
);
forkJoin
forkJoin is an RxJS operator that allows you to perform multiple HTTP requests or other asynchronous operations in parallel and then combine their results into a single observable.
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { forkJoin } from 'rxjs';
@Component({
  selector: 'app-example',
  template: `
    <div *ngIf="data">
      <p>Data from API 1: {{ data[0] }}</p>
      <p>Data from API 2: {{ data[1] }}</p>
    </div>
  `,
})
export class ExampleComponent implements OnInit {
  data: any[];
  constructor(private http: HttpClient) {}
  ngOnInit() {
    // Make multiple HTTP requests in parallel using forkJoin
    const api1$ = this.http.get('https://api.example.com/data1');
    const api2$ = this.http.get('https://api.example.com/data2');
    forkJoin([api1$, api2$]).subscribe(
      (results) => {
        // results[0] is the result of the first HTTP request
        // results[1] is the result of the second HTTP request
        this.data = results;
      },
      (error) => {
        console.error('Error:', error);
      }
    );
  }
}
Conclusion
These are just a few examples, and there are many more RxJS operators available for various use cases. Understanding and effectively using RxJS operators is crucial for handling complex asynchronous scenarios in Angular applications.