Skip to main content
Angular Basics
CHAPTER 20 Beginner

Observables and Subjects

Updated: May 18, 2026
5 min read

# CHAPTER 20

Observables and Subjects

1. Chapter Introduction

While regular Observables are passive (they only emit when something subscribes), Subjects are both an Observable AND an Observer. They can multicast values to multiple subscribers and be triggered programmatically. Understanding the four types of Subjects and the async pipe is fundamental for building real Angular applications.

2. Learning Objectives

  • Differentiate between Observable and Subject.
  • Use Subject, BehaviorSubject, and ReplaySubject appropriately.
  • Use the async pipe to manage subscriptions in templates.
  • Understand hot vs cold Observables.
  • Implement real data streams.

3. Subject

A Subject is a multicast Observable. Multiple subscribers receive the same emissions:
typescript
1234567891011121314
import { Subject } from 'rxjs';

const subject = new Subject<string>();

// Two different subscribers
subject.subscribe(val => console.log(&#039;Subscriber 1:&#039;, val));
subject.subscribe(val => console.log(&#039;Subscriber 2:&#039;, val));

subject.next(&#039;Hello&#039;); // Both receive 'Hello'
subject.next(&#039;World&#039;); // Both receive 'World'

// NOTE: Late subscribers miss previous emissions!
subject.subscribe(val => console.log(&#039;Late Sub:&#039;, val)); // Receives nothing for past
subject.next(&#039;New value&#039;); // Late sub receives 'New value'

4. BehaviorSubject

BehaviorSubject requires an initial value and always emits the current value to new subscribers:
typescript
123456789101112
import { BehaviorSubject } from &#039;rxjs&#039;;

const currentUser$ = new BehaviorSubject<string>(&#039;Guest&#039;);

currentUser$.subscribe(user => console.log(&#039;User A:&#039;, user)); // Immediately: 'Guest'

currentUser$.next(&#039;Alice&#039;);

// New subscriber gets the CURRENT value immediately!
currentUser$.subscribe(user => console.log(&#039;User B:&#039;, user)); // Immediately: 'Alice'

console.log(currentUser$.getValue()); // 'Alice'

Ideal for: Current user, cart count, theme preference, loading state — any value where new subscribers need the current state immediately.

5. ReplaySubject

ReplaySubject buffers N previous values and replays them to new subscribers:
typescript
1234567891011
import { ReplaySubject } from &#039;rxjs&#039;;

const replaySubject = new ReplaySubject<number>(3); // Buffer last 3

replaySubject.next(1);
replaySubject.next(2);
replaySubject.next(3);
replaySubject.next(4);

// New subscriber gets the last 3: 2, 3, 4
replaySubject.subscribe(val => console.log(&#039;Replay:&#039;, val));

Ideal for: Chat history, notification logs, browser history.

6. Subject Comparison

FeatureSubjectBehaviorSubjectReplaySubject
Initial valueNoneRequiredNone
Late subscribers getNothingCurrent valueLast N values
Use caseEvents/clicksCurrent stateHistory/log
.getValue()NoYesNo

7. The async Pipe

The async pipe is Angular's built-in solution for subscribing to Observables in templates. It automatically:
  1. 1. Subscribes to the Observable.
  1. 2. Updates the view when new values arrive.
  1. 3. Unsubscribes automatically when the component is destroyed (prevents memory leaks!).
typescript
123456
export class UserDashboardComponent {
  users$ = this.userService.getUsers(); // Observable, NOT subscribed
  isLoading$ = new BehaviorSubject<boolean>(true);

  constructor(private userService: UserService) {}
}
html
1234567891011121314
<!-- The async pipe handles everything! -->
<div *ngIf="isLoading$ | async">Loading...</div>

<ul>
  <li *ngFor="let user of users$ | async">
    {{ user.name }} — {{ user.email }}
  </li>
</ul>

<!-- For objects -->
<ng-container *ngIf="currentUser$ | async as user">
  <h2>Welcome, {{ user.name }}!</h2>
  <p>Role: {{ user.role }}</p>
</ng-container>

8. Hot vs Cold Observables

  • Cold Observable: Each subscriber gets its own independent stream. Example: http.get() — each subscriber triggers a separate HTTP request.
  • Hot Observable: Multiple subscribers share the same stream. Example: Subject, mouse events — subscribers share the same source.
typescript
123456789
// Cold — each subscribe makes a new HTTP call!
const cold$ = this.http.get(&#039;/api/data&#039;);
cold$.subscribe(); // Makes HTTP call #1
cold$.subscribe(); // Makes HTTP call #2

// Hot — share the same HTTP call
const hot$ = cold$.pipe(shareReplay(1));
hot$.subscribe(); // Makes HTTP call (once)
hot$.subscribe(); // Reuses the cached result

9. Common Mistakes

  • Using Subject when BehaviorSubject is needed: If a component needs to know the current cart count immediately on creation, a regular Subject won't provide it. Use BehaviorSubject.
  • Exposing BehaviorSubject directly: Never expose the BehaviorSubject itself from a service. Expose it as an Observable (.asObservable()) to prevent external components from calling .next().

10. MCQs with Answers

Question 1

What is the key difference between an Observable and a Subject?

Question 2

What does BehaviorSubject emit to a late subscriber?

Question 3

What initial setup is required for BehaviorSubject that Subject does not need?

Question 4

How do you retrieve a BehaviorSubject's current value without subscribing?

Question 5

What does ReplaySubject(3) buffer and emit to new subscribers?

Question 6

What three things does the async pipe automatically handle?

Question 7

What is a "Cold Observable"?

Question 8

What RxJS operator converts a Cold Observable to a Hot one and caches the result?

Question 9

Why should you expose a BehaviorSubject from a service as .asObservable() instead of directly?

Question 10

What is the *ngIf="data$ | async as data" pattern useful for?

11. Interview Questions

  • Q: What is the difference between Subject, BehaviorSubject, and ReplaySubject? Give a real-world use case for each.
  • Q: Why is the async pipe preferred over manual subscriptions in ngOnInit?

12. Summary

RxJS Subjects are the reactive communication backbone of Angular. BehaviorSubject is the go-to tool for shared application state. The async pipe elegantly solves subscription management in templates, preventing the most common Angular memory leak. Together, they enable building truly reactive, event-driven interfaces.

13. Next Chapter Recommendation

With a solid understanding of RxJS, we are ready to tackle authentication. In Chapter 21: Authentication and Authorization, we build a complete JWT-based login system with protected routes.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·