Here’s a detailed comparison and explanation of Subject
vs BehaviorSubject
in RxJS (Reactive Extensions for JavaScript)—widely used in Angular for state management, communication between components, and reactive programming.
✅ Subject
vs BehaviorSubject
in RxJS
Feature | Subject |
BehaviorSubject |
---|---|---|
Initial Value | ❌ Does not hold a default value | ✅ Requires an initial value |
Replay Last Value | ❌ New subscribers do not get previous emissions | ✅ New subscribers immediately receive the last emitted value |
Common Use Case | Events (e.g., button clicks, form submissions) | State or data (e.g., current user, theme, language settings) |
Value Access | ❌ Cannot access the current value directly | ✅ Can get current value via .value property |
Multicasting | ✅ Yes | ✅ Yes |
🔹 What is a Subject
?
A Subject
is a special type of Observable that allows multicasting to multiple observers.
🔧 Example:
const subject = new Subject<number>();
subject.subscribe(val => console.log('Subscriber 1:', val));
subject.next(1); // Output: Subscriber 1: 1
subject.subscribe(val => console.log('Subscriber 2:', val));
subject.next(2);
// Output:
// Subscriber 1: 2
// Subscriber 2: 2
❗ Note: Subscriber 2 didn't receive
1
because it subscribed after it was emitted.
🔹 What is a BehaviorSubject
?
A BehaviorSubject
stores the latest value and emits it immediately to new subscribers.
🔧 Example:
const behaviorSubject = new BehaviorSubject<number>(0); // Initial value
behaviorSubject.subscribe(val => console.log('Subscriber 1:', val));
// Output: Subscriber 1: 0 (gets initial value)
behaviorSubject.next(1);
behaviorSubject.subscribe(val => console.log('Subscriber 2:', val));
// Output: Subscriber 2: 1 (gets last emitted value)
behaviorSubject.next(2);
// Output:
// Subscriber 1: 2
// Subscriber 2: 2
🔍 Accessing Current Value (BehaviorSubject only):
const value = behaviorSubject.value;
console.log('Current Value:', value);
🧠 When to Use Which?
Use Case | Use |
---|---|
You want to broadcast events (no stored value) | Subject |
You need to remember the last value or have a default | BehaviorSubject |
You want new subscribers to immediately get the latest data | BehaviorSubject |
✅ Summary
- Use
Subject
for one-off events. - Use
BehaviorSubject
for holding current state and updating all listeners.
Sure! Let's go through real-world, project-based examples of how Subject
and BehaviorSubject
are used in Angular applications, especially for communication between components and state management.
📦 Project Scenario: Angular E-commerce App
🎯 Use Case 1: Cart State Management (Using BehaviorSubject
)
You want to maintain a global cart state and reflect updates across components like the header, cart page, and product list.
✅ Service (cart.service.ts
)
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Injectable({ providedIn: 'root' })
export class CartService {
private cartItems = new BehaviorSubject<any[]>([]);
cartItems$ = this.cartItems.asObservable();
addToCart(product: any) {
const currentItems = this.cartItems.value;
this.cartItems.next([...currentItems, product]);
}
removeFromCart(productId: string) {
const updatedItems = this.cartItems.value.filter(p => p.id !== productId);
this.cartItems.next(updatedItems);
}
getCartItems() {
return this.cartItems.value;
}
}
🧩 Header Component (header.component.ts
) – Show cart count
this.cartService.cartItems$.subscribe(items => {
this.cartCount = items.length;
});
📦 Cart Page (cart.component.ts
) – Show cart details
this.cartService.cartItems$.subscribe(items => {
this.cartItems = items;
});
💡 Why BehaviorSubject
?
- Holds the latest cart state.
- Any new subscriber (component) instantly gets current cart items.
- Easily allows centralized state management.
🎯 Use Case 2: Notification System (Using Subject
)
You want to show toast notifications (success, error, etc.) triggered by different parts of the app.
✅ Notification Service (notification.service.ts
)
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
@Injectable({ providedIn: 'root' })
export class NotificationService {
private notificationSubject = new Subject<string>();
notification$ = this.notificationSubject.asObservable();
show(message: string) {
this.notificationSubject.next(message);
}
}
🧩 Notification Component (notification.component.ts
)
this.notificationService.notification$.subscribe(msg => {
this.message = msg;
// Display the toast
});
🧩 Trigger Notification From Anywhere
this.notificationService.show('Product added to cart!');
💡 Why Subject
?
- Only emits when a new event occurs.
- No need to store previous values.
- Ideal for short-lived, one-time event streams.
🎯 Use Case 3: Login State Management (Using BehaviorSubject
)
Track user login status and show/hide UI elements conditionally.
✅ Auth Service (auth.service.ts
)
private isLoggedInSubject = new BehaviorSubject<boolean>(false);
isLoggedIn$ = this.isLoggedInSubject.asObservable();
login(userCredentials) {
// after successful login
this.isLoggedInSubject.next(true);
}
logout() {
this.isLoggedInSubject.next(false);
}
🧩 Sidebar Component
this.authService.isLoggedIn$.subscribe(loggedIn => {
this.showMenu = loggedIn;
});
✅ Summary
Feature | Subject | BehaviorSubject |
---|---|---|
When to Use | Emit events without state (e.g., notifications) | Share application state (e.g., cart, login info) |
Project Example | Toast notifications, chat messages | Cart management, login state, theme switching |
Happy Coding!
Top comments (0)