Angular Subjects
Learn Angular Subjects with Subject, BehaviorSubject, ReplaySubject, AsyncSubject, multicasting, state sharing, architecture diagrams, enterprise examples, best practices, and interview questions.
Subjects are one of the most powerful features of RxJS.
Unlike regular Observables, a Subject is both:
- An Observable
- An Observer
This allows a Subject to:
- Receive data
- Emit data
- Broadcast data to multiple subscribers
Subjects are widely used in enterprise Angular applications for:
- State Sharing
- Event Communication
- Notifications
- Authentication State
- Shopping Cart Updates
- Theme Switching
- Real-Time Dashboards
- WebSocket Communication
Subjects are one of the most frequently asked Angular interview topics.
Table of Contents
- What is a Subject?
- Why Use Subjects?
- Subject Architecture
- Creating a Subject
- Subject vs Observable
- BehaviorSubject
- ReplaySubject
- AsyncSubject
- Subject Comparison
- Enterprise Banking Example
- Performance Best Practices
- Common Mistakes
- Top 10 Interview Questions
- Summary
What is a Subject?
A Subject is a special type of Observable that can both:
- Emit values
- Receive values
Unlike a normal Observable, a Subject multicasts values to all active subscribers.
Example
Subject
↓
Subscriber A
Subscriber B
Subscriber C
Subject Architecture
flowchart TD
Subject
Subject --> ComponentA
Subject --> ComponentB
Subject --> ComponentC
Why Use Subjects?
Without Subjects
- Components communicate indirectly
- Duplicate API calls
- Difficult event sharing
- Poor scalability
With Subjects
- Shared state
- Event broadcasting
- Better communication
- Centralized updates
- Improved scalability
Creating a Subject
import { Subject } from 'rxjs';
const messageSubject =
new Subject<string>();
Publishing values
messageSubject.next(
'Welcome'
);
messageSubject.next(
'Angular'
);
Subscribing
messageSubject.subscribe(
message =>
console.log(
'A:',
message
)
);
messageSubject.subscribe(
message =>
console.log(
'B:',
message
)
);
Output
A: Welcome
B: Welcome
A: Angular
B: Angular
Subject Flow
sequenceDiagram
participant Publisher
participant Subject
participant ComponentA
participant ComponentB
Publisher->>Subject: next("Hello")
Subject-->>ComponentA: Hello
Subject-->>ComponentB: Hello
Subject vs Observable
| Observable | Subject |
|---|---|
| Data Producer | Producer + Consumer |
| Unicast by default | Multicast |
| Read-only stream | Can emit using next() |
| Created with Observable | Created with Subject |
| Subscribers get separate execution | Subscribers share emissions |
Subject vs Observable Architecture
flowchart LR
Observable --> Subscriber1
Observable --> Subscriber2
Subject --> Component1
Subject --> Component2
Subject --> Component3
BehaviorSubject
A BehaviorSubject stores the latest value.
New subscribers immediately receive the current value.
Example
import {
BehaviorSubject
} from 'rxjs';
const counter =
new BehaviorSubject<number>(0);
counter.next(1);
counter.next(2);
counter.subscribe(
value =>
console.log(value)
);
Output
2
The latest value is emitted immediately.
BehaviorSubject Architecture
flowchart TD
BehaviorSubject
BehaviorSubject --> CurrentValue
CurrentValue --> ComponentA
CurrentValue --> ComponentB
BehaviorSubject Example
Authentication Service
@Injectable({
providedIn:'root'
})
export class AuthService{
private loggedInSubject =
new BehaviorSubject<boolean>(false);
isLoggedIn$ =
this.loggedInSubject.asObservable();
login(){
this.loggedInSubject.next(true);
}
logout(){
this.loggedInSubject.next(false);
}
}
Component
this.authService
.isLoggedIn$
.subscribe(
status =>{
this.loggedIn = status;
}
);
Using asObservable() exposes a read-only Observable, preventing consumers from calling next() directly.
ReplaySubject
A ReplaySubject stores multiple previous values and replays them to new subscribers.
Example
import {
ReplaySubject
} from 'rxjs';
const replay =
new ReplaySubject<number>(3);
replay.next(10);
replay.next(20);
replay.next(30);
replay.next(40);
replay.subscribe(
console.log
);
Output
20
30
40
The last three values are replayed.
ReplaySubject Architecture
flowchart TD
ReplaySubject
ReplaySubject --> Last3Values
Last3Values --> Component
AsyncSubject
An AsyncSubject emits only the final value after the source completes.
Example
import {
AsyncSubject
} from 'rxjs';
const asyncSubject =
new AsyncSubject<number>();
asyncSubject.next(10);
asyncSubject.next(20);
asyncSubject.next(30);
asyncSubject.complete();
asyncSubject.subscribe(
console.log
);
Output
30
Without calling complete(), subscribers will not receive the final value.
AsyncSubject Architecture
flowchart LR
Values
Values --> AsyncSubject
AsyncSubject --> Complete
Complete --> Subscriber
Subject Comparison
| Feature | Subject | BehaviorSubject | ReplaySubject | AsyncSubject |
|---|---|---|---|---|
| Initial Value | No | Yes | No | No |
| Current Value | No | Yes | Yes (buffer) | Final Only |
| Replay Previous Values | No | Latest Only | Configurable | Final Only |
| Emits Without Completion | Yes | Yes | Yes | No |
| Typical Use | Events | Application State | History | Final Result |
Choosing the Right Subject
| Requirement | Recommended Type |
|---|---|
| Event Bus | Subject |
| Authentication State | BehaviorSubject |
| Theme Switching | BehaviorSubject |
| Chat History | ReplaySubject |
| Notification History | ReplaySubject |
| Final Computation Result | AsyncSubject |
Enterprise Banking Example
Internet Banking Dashboard
Subjects Used
- Authentication State
- Notification Stream
- Account Selection
- Theme Changes
- Live Balance
- Market Alerts
Architecture
flowchart TD
AngularApp
AngularApp --> AuthService
AngularApp --> NotificationService
AngularApp --> DashboardService
AuthService --> BehaviorSubject
NotificationService --> Subject
DashboardService --> ReplaySubject
BehaviorSubject --> Components
Subject --> Components
ReplaySubject --> Components
Benefits
- Shared application state
- Live updates
- Better component communication
- Reduced duplicate requests
- Cleaner architecture
Subject Lifecycle
flowchart TD
A["Create Subject"]
B["Subscribe"]
C["next()"]
D["Subscribers"]
E["Complete"]
A --> B
B --> C
C --> D
D --> E
Performance Best Practices
| Practice | Benefit |
|---|---|
Use BehaviorSubject for application state |
Current value available |
Use Subject for events |
Lightweight event broadcasting |
| Limit ReplaySubject buffer size | Lower memory usage |
Expose Subjects using asObservable() |
Better encapsulation |
| Complete Subjects when appropriate | Resource cleanup |
| Avoid global event buses for unrelated features | Better maintainability |
Common Mistakes
Exposing Subjects Directly
Avoid
public userSubject =
new BehaviorSubject<User|null>(null);
Better
private userSubject =
new BehaviorSubject<User|null>(null);
user$ =
this.userSubject.asObservable();
This prevents external code from calling next().
Using ReplaySubject Without Buffer Limits
Bad
new ReplaySubject();
Better
new ReplaySubject(5);
An unlimited buffer can consume significant memory over time.
Using BehaviorSubject Without an Initial Value
BehaviorSubject requires an initial value.
Example
new BehaviorSubject<number>(0);
Using Subject for Shared State
If new subscribers need the latest state immediately, prefer BehaviorSubject instead of Subject.
Forgetting to Complete Subjects
Complete Subjects that represent finite lifecycles when appropriate, especially if they own resources. Long-lived application-wide Subjects (for example, in singleton services) may intentionally remain active for the application's lifetime.
Best Practices
- Use
Subjectfor event broadcasting. - Use
BehaviorSubjectfor shared application state. - Use
ReplaySubjectonly with a reasonable buffer size. - Use
AsyncSubjectfor final-result scenarios. - Expose read-only Observables using
asObservable(). - Avoid unnecessary Subjects.
- Keep Subjects private.
- Prefer immutable state updates.
- Unsubscribe from long-lived subscriptions where required.
- Write unit tests for Subject-based services.
Advantages
| Subject Type | Benefit |
|---|---|
| Subject | Simple multicasting |
| BehaviorSubject | Current state |
| ReplaySubject | Replay history |
| AsyncSubject | Final value after completion |
| Enterprise Ready | Scalable communication |
Top 10 Angular Subjects Interview Questions
1. What is a Subject?
Answer
A Subject is a special RxJS type that acts as both an Observable and an Observer, allowing values to be emitted and multicasted to multiple subscribers.
2. What is the difference between Subject and Observable?
Answer
A regular Observable is unicast by default and produces values for each subscriber separately, while a Subject multicasts the same emitted values to all subscribers.
3. What is a BehaviorSubject?
Answer
A BehaviorSubject stores the latest value and immediately emits it to new subscribers. It requires an initial value.
4. What is a ReplaySubject?
Answer
A ReplaySubject stores a configurable number of previous values and replays them to new subscribers.
5. What is an AsyncSubject?
Answer
An AsyncSubject emits only the last value after the source completes.
6. When should you use a Subject?
Answer
Use a Subject for event broadcasting where subscribers only need future events.
7. When should you use a BehaviorSubject?
Answer
Use a BehaviorSubject for shared application state, such as authentication status, selected language, or theme.
8. Why use asObservable()?
Answer
asObservable() exposes a read-only Observable so consumers can subscribe without being able to emit new values.
9. What are common Subject use cases?
Answer
- Authentication state
- Shopping cart updates
- Notifications
- Theme switching
- Event buses
- WebSocket messages
10. What are Subject best practices?
Answer
- Keep Subjects private.
- Expose Observables using
asObservable(). - Choose the correct Subject type.
- Limit ReplaySubject buffers.
- Avoid unnecessary Subjects.
- Manage subscriptions appropriately.
Interview Cheat Sheet
| Topic | Remember |
|---|---|
| Event Broadcasting | Subject |
| Shared State | BehaviorSubject |
| History | ReplaySubject |
| Final Value | AsyncSubject |
| Current Value | BehaviorSubject |
| Multicasting | Subject |
| Read-only API | asObservable() |
| Buffer Size | ReplaySubject |
| Initial Value | BehaviorSubject |
| Best Practice | Keep Subjects private |
Summary
RxJS Subjects provide a powerful multicasting mechanism that enables efficient communication between Angular components and services. While a standard Subject is ideal for event broadcasting, BehaviorSubject excels at managing shared state, ReplaySubject allows replaying historical values, and AsyncSubject emits the final value after completion. Selecting the appropriate Subject type and exposing it safely through asObservable() helps build scalable, maintainable, and enterprise-ready Angular applications.
Key Takeaways
- ✔ A Subject is both an Observable and an Observer.
- ✔ Subjects multicast values to multiple subscribers.
- ✔ Use
BehaviorSubjectfor shared state. - ✔ Use
ReplaySubjectwhen previous values must be replayed. - ✔ Use
AsyncSubjectfor final-result scenarios. - ✔ Expose Subjects using
asObservable(). - ✔ Keep Subjects private.
- ✔ Limit ReplaySubject buffer sizes.
- ✔ Choose the appropriate Subject type for the use case.
- ✔ Subjects are one of the most important Angular and RxJS interview topics.
Next Article
➡️ 73-BehaviorSubject-vs-Subject-QA.md