← Back to Articles         
What is RxJS in Angular?

What is RxJS in Angular?

Published on 01 Oct 2026     10 min read Angular
RxJS & Observables

1. What is RxJS?

RxJS stands for Reactive Extensions for JavaScript.

RxJS is a JavaScript library for handling asynchronous operations and streams of data using Observables.

In Angular, RxJS is commonly used for:

  • HTTP API calls
  • Handling asynchronous data
  • User events
  • Form value changes
  • Route parameters
  • Search/autocomplete
  • Timers
  • Combining multiple API calls
  • Error handling and retry logic
  • Communication between components/services

The most important concept in RxJS is the Observable.

Simple idea

Think of an Observable as a data producer that can provide values over time.

Observable
    │
    ├── value 1
    ├── value 2
    ├── value 3
    │
    └── complete
         ↓
    Subscriber

For example, an HTTP request:

Angular Component
       │
       │ subscribe()
       ▼
   Observable
       │
       │ HTTP Request
       ▼
    Web API
       │
       │ Response
       ▼
Observable emits data
       │
       ▼
Component receives data

2. Full Simple Sample Program

Consider a simple Angular application that retrieves products from an API using HttpClient.

The important point is:

Angular HttpClient methods such as get(), post(), put(), and delete() return RxJS Observables.

app.config.ts

import { ApplicationConfig } from '@angular/core';
import { provideHttpClient } from '@angular/common/http';

export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient()
  ]
};

product.ts

export interface Product {
  id: number;
  name: string;
  price: number;
}

product.service.ts

import { Injectable, inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

import { Product } from './product';

@Injectable({
  providedIn: 'root'
})
export class ProductService {

  private http = inject(HttpClient);

  private apiUrl = 'https://localhost:7001/api/products';

  getProducts(): Observable<Product[]> {
    return this.http.get<Product[]>(this.apiUrl);
  }
}

product-list.ts

import { Component, OnInit, inject } from '@angular/core';
import { ProductService } from './product.service';
import { Product } from './product';

@Component({
  selector: 'app-product-list',
  standalone: true,
  templateUrl: './product-list.html'
})
export class ProductList implements OnInit {

  private productService = inject(ProductService);

  products: Product[] = [];

  ngOnInit(): void {

    this.productService.getProducts()
      .subscribe({
        next: (data) => {
          this.products = data;
        },

        error: (error) => {
          console.error('Error:', error);
        },

        complete: () => {
          console.log('Request completed');
        }
      });
  }
}

product-list.html

<h2>Products</h2>

@for (product of products; track product.id) {

  <div>
    <h3>{{ product.name }}</h3>

    <p>
      Price: {{ product.price }}
    </p>
  </div>

}

3. Program Explanation

The important RxJS code is:

getProducts(): Observable<Product[]> {
  return this.http.get<Product[]>(this.apiUrl);
}

HttpClient.get() returns an Observable.

Therefore:

Observable<Product[]>

means:

This Observable will produce an array of Product objects.

Notice that we are not receiving the products immediately.

We are returning an Observable representing the asynchronous HTTP operation.


4. What is an Observable?

An Observable represents a stream of values that may arrive now or later.

Example:

Observable<Product[]>

The Observable may eventually emit:

[
  { id: 1, name: 'Laptop', price: 75000 },
  { id: 2, name: 'Mouse', price: 1500 }
]

An Observable can emit:

Observable
    │
    ├── next(value)
    ├── next(value)
    ├── next(value)
    │
    ├── error(error)
    │
    └── complete()

There are three important notification types:

Notification Meaning
next A value has been produced
error Something failed
complete No more values will be produced

5. What is subscribe()?

To receive values from an Observable, we can subscribe to it.

this.productService.getProducts()
  .subscribe({
    next: (data) => {
      this.products = data;
    }
  });

Think of it as:

Observable = YouTube Channel
Subscriber = Viewer subscribing to channel
Emission   = New video notification

When the Observable produces a value, subscribers receive it.


6. next, error, and complete

A complete subscription can contain:

this.productService.getProducts()
  .subscribe({

    next: (data) => {
      console.log(data);
    },

    error: (error) => {
      console.error(error);
    },

    complete: () => {
      console.log('Completed');
    }

  });

next

Receives emitted values:

next: (data) => {
  console.log(data);
}

error

Executed when an error occurs:

error: (error) => {
  console.error(error);
}

For example:

500 Internal Server Error
404 Not Found
Network error

complete

Runs when the Observable finishes successfully:

complete: () => {
  console.log('Completed');
}

7. RxJS Is Not Only for HTTP

A common misunderstanding is:

RxJS is used only for API calls.

No. RxJS can represent many kinds of asynchronous data streams.

For example:

HTTP responses
User clicks
Keyboard events
Form changes
Route parameters
Timers
WebSocket messages
Search text
Application events

8. Simple RxJS Example Without HTTP

We can create an Observable using of().

import { of } from 'rxjs';

const numbers$ = of(10, 20, 30);

numbers$.subscribe({
  next: value => console.log(value),
  complete: () => console.log('Completed')
});

Output:

10
20
30
Completed

Flow:

of(10, 20, 30)
      │
      ▼
  Observable
      │
      ├── 10
      ├── 20
      ├── 30
      └── complete
            │
            ▼
        Subscriber

9. Observable Can Emit Multiple Values

This is one major reason Observables are powerful.

For example:

import { interval } from 'rxjs';

const numbers$ = interval(1000);

numbers$.subscribe(value => {
  console.log(value);
});

Output:

0
1
2
3
4
...

A new value is emitted every second.

Therefore an Observable is naturally suitable for streams of values over time.


10. What are RxJS Operators?

RxJS provides operators that allow us to transform, filter, combine, delay, retry, or otherwise process Observable values.

Common operators include:

map
filter
tap
switchMap
mergeMap
concatMap
debounceTime
distinctUntilChanged
catchError
retry
take
takeUntil
forkJoin
combineLatest

Example:

import { of } from 'rxjs';
import { map } from 'rxjs/operators';

const numbers$ = of(1, 2, 3);

numbers$
  .pipe(
    map(number => number * 10)
  )
  .subscribe(value => {
    console.log(value);
  });

Output:

10
20
30

Flow:

Observable
1 → 2 → 3
    │
    ▼
 map(x => x * 10)
    │
    ▼
10 → 20 → 30
    │
    ▼
Subscriber

11. What is pipe()?

pipe() allows us to apply RxJS operators to an Observable.

Example:

numbers$
  .pipe(
    map(x => x * 10)
  )
  .subscribe(x => console.log(x));

Multiple operators can be chained:

numbers$
  .pipe(
    filter(x => x > 5),
    map(x => x * 10)
  )
  .subscribe(x => console.log(x));

Think of it as a processing pipeline:

Observable
    │
    ▼
 filter()
    │
    ▼
 map()
    │
    ▼
Subscriber

12. Real Angular Example — Search

RxJS becomes especially useful when dealing with continuously changing values.

For example, suppose a user types:

L
La
Lap
Lapt
Lapto
Laptop

We don't want to call the Web API for every keystroke.

RxJS can use:

debounceTime()
distinctUntilChanged()
switchMap()

Conceptually:

User types
    │
    ▼
valueChanges
    │
    ▼
debounceTime(300)
    │
    ▼
distinctUntilChanged()
    │
    ▼
switchMap()
    │
    ▼
HTTP API

This is one of the classic real-world uses of RxJS in Angular.


13. Observable vs Promise

Both are used for asynchronous programming, but they are different.

Feature Observable Promise
Library RxJS JavaScript
Values Zero, one, or many One eventual result
Lazy Usually yes Starts when created
Operators Many RxJS operators Limited
Cancellation/unsubscription Supported Not directly
Streaming Excellent Not designed for streams
Angular usage Very common Also possible

Example Promise:

fetch('/api/products')
  .then(response => response.json())
  .then(data => console.log(data));

Observable:

this.http.get<Product[]>('/api/products')
  .subscribe(data => {
    console.log(data);
  });

Angular's HttpClient uses Observables.


14. Observable vs Subscriber

These two terms should not be confused.

Observable

The producer/source of values.

const numbers$ = of(10, 20, 30);

Subscriber

The code interested in receiving those values.

numbers$.subscribe(value => {
  console.log(value);
});

Conceptually:

Producer                         Consumer

Observable  ──────────────────► Subscriber
                values

15. What is a Subscription?

When we call:

observable.subscribe(...)

RxJS returns a Subscription.

Example:

const subscription = numbers$.subscribe(value => {
  console.log(value);
});

We can stop the subscription:

subscription.unsubscribe();

This is especially important for long-running streams such as:

interval()
WebSocket
Form valueChanges
Custom event streams

However, Angular also provides modern mechanisms such as AsyncPipe and takeUntilDestroyed() that can simplify subscription lifecycle management.


16. What is a Subject?

A Subject is a special type of Observable that can both:

  • emit values
  • allow subscribers to receive values

Example:

import { Subject } from 'rxjs';

const message$ = new Subject<string>();

message$.subscribe(message => {
  console.log('Subscriber 1:', message);
});

message$.subscribe(message => {
  console.log('Subscriber 2:', message);
});

message$.next('Hello');

Output:

Subscriber 1: Hello
Subscriber 2: Hello

Conceptually:

                  ┌──► Subscriber 1
Subject ──────────┤
                  └──► Subscriber 2

Subjects are often encountered when implementing shared event/data streams in Angular services.


17. Important RxJS Concepts

When learning RxJS for Angular, understand these concepts in roughly this progression:

RxJS
 │
 ├── Observable
 │
 ├── subscribe()
 │
 ├── Subscription
 │
 ├── pipe()
 │
 ├── Operators
 │    ├── map
 │    ├── filter
 │    ├── tap
 │    ├── debounceTime
 │    ├── switchMap
 │    └── catchError
 │
 └── Subjects
      ├── Subject
      ├── BehaviorSubject
      └── ReplaySubject

You don't need to memorize every RxJS operator. For Angular development, mastering the common operators and understanding Observable flow is much more important.


Key Points

  • RxJS = Reactive Extensions for JavaScript.
  • RxJS is a library for reactive and asynchronous programming.
  • The core RxJS concept is the Observable.
  • An Observable represents a stream of values over time.
  • subscribe() allows a consumer to receive Observable values.
  • Observable notifications are primarily next, error, and complete.
  • Angular's HttpClient returns Observables.
  • pipe() is used to compose Observable operators.
  • Operators such as map, filter, switchMap, debounceTime, and catchError process Observable streams.
  • A Subscription represents an active subscription and can be unsubscribed when appropriate.
  • Subject is both an Observable and an observer-like source that can emit values.
  • RxJS is useful for HTTP, forms, events, routing, timers, WebSockets, and many other asynchronous scenarios.

Interview Questions and Answers

1. What is RxJS?

Answer:
RxJS stands for Reactive Extensions for JavaScript. It is a library for reactive and asynchronous programming using Observables and provides operators for processing streams of data.

2. What is an Observable?

Answer:
An Observable represents a stream of values that can be emitted over time. Consumers can subscribe to the Observable to receive those values.

3. Why does Angular use RxJS?

Answer:
Angular applications contain many asynchronous operations such as HTTP requests, form changes, route changes, and user events. RxJS provides a consistent way to represent and process these asynchronous streams.

4. What does subscribe() do?

Answer:
subscribe() starts listening to an Observable and provides handlers for emitted values, errors, and completion.

observable.subscribe({
  next: value => console.log(value),
  error: error => console.error(error),
  complete: () => console.log('Completed')
});

5. What are next, error, and complete?

Answer:

  • next — receives an emitted value.
  • error — receives an error and terminates the stream.
  • complete — indicates successful completion of the stream.

6. What is an RxJS operator?

Answer:
An operator is a function used to transform, filter, combine, or otherwise process values emitted by an Observable.

Examples:

map()
filter()
switchMap()
debounceTime()
catchError()

7. What is pipe()?

Answer:
pipe() is used to compose one or more RxJS operators and apply them to an Observable.

observable.pipe(
  filter(x => x > 10),
  map(x => x * 2)
);

8. Does Angular HttpClient return a Promise or Observable?

Answer:
Angular HttpClient methods return RxJS Observables.

this.http.get<Product[]>(url);

The return type is:

Observable<Product[]>

9. Can an Observable emit multiple values?

Answer:
Yes. An Observable can emit zero, one, or multiple values over time. This makes Observables suitable for events, form changes, WebSockets, and other streams.

10. What is the difference between Observable and Promise?

Answer:
A Promise represents one eventual result, whereas an Observable can represent a stream of multiple values and supports rich operator composition and unsubscription.

11. What is a Subject?

Answer:
A Subject is a special RxJS type that can emit values through next() while also allowing multiple consumers to subscribe to those values.

12. What is RxJS in one interview sentence?

RxJS is a reactive programming library for JavaScript that uses Observables to represent and process asynchronous streams of data.

← Back to Articles