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 Subject for event broadcasting.
  • Use BehaviorSubject for shared application state.
  • Use ReplaySubject only with a reasonable buffer size.
  • Use AsyncSubject for 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 BehaviorSubject for shared state.
  • ✔ Use ReplaySubject when previous values must be replayed.
  • ✔ Use AsyncSubject for 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