Subjects
Subjects are both Observable and Observer. They are the foundation of multicasting and state management in Angular services.
A Subject is a special type of Observable that is BOTH an Observable (you can subscribe) AND an Observer (you can push values).
"Subject = announcement speaker โ you can listen AND you can speak."
import { Subject } from 'rxjs';
// Create a Subject
const notification$ = new Subject();
// Subscribe to it (like Observable)
notification$.subscribe(msg => console.log('Listener 1:', msg));
// Push values to it (like Observer)
notification$.next('๐ Biryani ready!');
// Listener 1: ๐ Biryani ready!
// Late subscribers miss previous values
notification$.next('๐ฅ New curry added!');
// Listener 1: ๐ฅ New curry added!
// New subscriber below MISSES "Biryani ready!"
notification$.subscribe(msg => console.log('Listener 2:', msg));
Key facts about Subjects:
- Used for cross-component communication (service โ multiple components)
- Multicast โ one Subject, many subscribers share same execution
- New subscribers miss previous values (except BehaviorSubject/ReplaySubject)
- Don't forget to complete() when done to avoid memory leaks
Subject is the basic type โ no replay, no initial value. New subscribers only get values emitted AFTER they subscribe.
import { Subject } from 'rxjs';
const subject = new Subject();
// Late subscriber โ misses 1 and 2
setTimeout(() => {
subject.subscribe(v => console.log('Late:', v)); // Only sees 3
}, 1000);
subject.next(1);
subject.next(2);
setTimeout(() => subject.next(3), 2000);
"Subject = live radio โ jo abhi bol rahe wo sunao, purana nahi."
Use cases for Subject:
- Event bus for one-time notifications
- Button click events, form submit events
- Any "fire and forget" event where history doesn't matter
โ ๏ธ Best practice: Always expose Subject as Observable to prevent external code from calling .next():
private refreshSubject = new Subject();
// Public as Observable only โ components can subscribe but not emit
refresh$ = this.refreshSubject.asObservable();
// Only this service can call next()
triggerRefresh() {
this.refreshSubject.next();
} BehaviorSubject is the most used Subject type. It requires an initial value and replays the LAST value to new subscribers.
import { BehaviorSubject } from 'rxjs';
// REQUIRES initial value
const userSubject = new BehaviorSubject(null);
// Subscribe immediately gets current value
userSubject.subscribe(user => console.log('User:', user));
// Output: User: null (initial value)
// Push a new value
userSubject.next({ id: 1, name: 'Shaik' });
// Output: User: { id: 1, name: 'Shaik' }
// New subscriber gets LAST value immediately
setTimeout(() => {
userSubject.subscribe(user => console.log('Late:', user));
// Output: Late: { id: 1, name: 'Shaik' } โ gets latest immediately!
}, 5000);
"BehaviorSubject = DVR โ join late bhi ho, last episode dikh jayega."
Why BehaviorSubject is the MOST USED Subject in Angular:
- All components always have the current state โ even if they subscribe late
- Initial value prevents "undefined" errors
.getValue()โ get current value synchronously (for imperative use)
BehaviorSubject is the foundation of the service state management pattern in Angular.
ReplaySubject replays a configurable number of past values to new subscribers.
import { ReplaySubject } from 'rxjs';
// ReplaySubject(bufferSize) โ replay last N values
const chatMessages$ = new ReplaySubject(3); // Replay last 3
chatMessages$.next('Hello');
chatMessages$.next('Kya haal hai?');
chatMessages$.next('Biryani khao?');
chatMessages$.next('Chalo khaate hain!');
// New subscriber gets last 3 messages
chatMessages$.subscribe(msg => console.log(msg));
// Output: 'Kya haal hai?', 'Biryani khao?', 'Chalo khaate hain!'
"ReplaySubject = highlights reel โ last 3 moments dikhao."
Use cases for ReplaySubject:
- Chat message history
- Audit logs
- Notification feed (last N items)
- Any scenario where late subscribers should see recent history
With Infinity buffer: new ReplaySubject(Infinity) โ replays ALL past values (use carefully, memory grows unbounded).
AsyncSubject emits ONLY the LAST value, and ONLY AFTER complete() is called.
import { AsyncSubject } from 'rxjs';
const result$ = new AsyncSubject();
result$.subscribe(v => console.log('Result:', v));
// No output yet โ still waiting for complete()
result$.next(1);
result$.next(2);
result$.next(42); // This will be the LAST value
// Nothing emitted yet! No complete() called
result$.complete();
// NOW output: Result: 42 (only the LAST value)
"AsyncSubject = exam result โ sab wait karo, result ek baar aayega."
Rarely used in Angular โ but good to know.
Use cases: Result of a computation that runs once and completes (like a Promise alternative).
Subject types comparison:
Subject โ No replay, no initial value
BehaviorSubject โ Replays 1 (last value), requires initial value
ReplaySubject โ Replays N (configurable), optional initial value
AsyncSubject โ Replays 1 (last), but ONLY after complete()Key Takeaways
- โ Subject = BOTH Observable and Observer โ subscribe to listen, .next() to emit
- โ Subject โ no replay (late subscribers miss previous values), for events/notifications
- โ BehaviorSubject โ replays last value, REQUIRES initial value, MOST USED in Angular services
- โ ReplaySubject(N) โ replays last N values, for chat/log history
- โ AsyncSubject โ emits last value only after complete(), like a Promise
Want to track your progress?
Log in to save your place and pick up where you left off.
Progress track karna chahte ho?
Login karo apni progress save karne ke liye aur jahan chhoda tha wahan se shuru karo.
Login