This content originally appeared on DEV Community and was authored by vetriselvan Panneerselvam
👋 Hey Devs,
Welcome back to another weekly deep dive! 🚀
This time, we’re exploring an incredibly useful and powerful concept in RxJS — the ReplaySubject
.
In our previous posts, we covered how to pass values asynchronously using Subject
and BehaviorSubject
. Today, we’ll focus on how ReplaySubject
differs and why it’s helpful when you want new subscribers to receive previously emitted values.
🔁 What is a ReplaySubject?
A ReplaySubject
is similar to a BehaviorSubject
, but with a twist — it can replay multiple previously emitted values to new subscribers, not just the latest one.
✅ Syntax:
const replaySubject = new ReplaySubject(2);
Here, the 2
represents the buffer size — meaning new subscribers will receive the last 2 emitted values upon subscription.
⚠️ Note: Unlike
BehaviorSubject
,ReplaySubject
does not require an initial value. If you subscribe before emitting any values, you’ll receive nothing.
🧪 Example in Angular
Let’s take a look at a working example where we use ReplaySubject
in an Angular app.
🧩 HTML:
<h3>ReplaySubject</h3>
<div class="text-wrapper">
<div class="text">
<textarea
class="textarea-modern"
[(ngModel)]="replaySubjectText"
name="replaySubject"
id="replaySubject"
></textarea>
<div class="btn-container">
<button class="btn-ghost" (click)="sendReplaySubject()" type="button">Send</button>
<button class="btn-ghost" (click)="addReplaySubject()" type="button">Add</button>
</div>
</div>
<div class="example">
@for (item of replaySubjectArray(); track $index) {
@let data = replayObservable | async;
<div class="card">
<div class="index">{{$index}}</div>
@if (data && data.length > 0) {
@for (item of data; track item; let i = $index) {
<div class="card">
<div class="index">{{i}}</div>
<div class="data">{{item | json}}</div>
</div>
}
} @else {
<div class="data">{{data | json}}</div>
}
</div>
}
</div>
</div>
🔧 TypeScript:
import { Component, model, OnInit, signal } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ReplaySubject, scan } from 'rxjs';
import { FormsModule } from '@angular/forms';
@Component({
selector: 'app-rxjs-operator',
imports: [CommonModule, FormsModule],
templateUrl: './rxjs-operator.html',
styleUrl: './rxjs-operator.scss',
})
export class RxjsOperator implements OnInit {
replaySubject = new ReplaySubject<string>(2);
replayObservable = this.replaySubject.asObservable().pipe(
scan((acc: string[], curr: string) => [...acc, curr], [])
);
replaySubjectText = model<string>('');
replaySubjectArray = signal<number[]>([0]);
ngOnInit(): void {}
sendReplaySubject() {
this.replaySubject.next(this.replaySubjectText());
}
addReplaySubject() {
this.replaySubjectArray.update((prev) => [...prev, 1]);
}
}
🧪 Use Case Breakdown
📍 Case 1: Initial Load
When the component loads, the ReplaySubject
is subscribed to, but no values have been emitted yet — so the UI displays null
or empty output.
📸 Refer to the screenshot showing the initial state (empty or
null
output).
📍 Case 2: Emitting New Values
When you enter a value in the textarea and click the Send button, that value is emitted via replaySubject.next()
. We use the scan
operator to accumulate emitted values for display.
🛠 We'll cover
scan
in more detail in an upcoming blog post!
📍 Case 3: New Subscribers, Old Data
After emitting more than two values (our buffer size is 2), clicking the Add button creates a new subscriber. That new subscriber immediately receives the last two emitted values — this is the magic of ReplaySubject
.
Any newly emitted values will be received by all active subscribers, just like with a regular Subject
.
🔍 Under the Hood
Internally, ReplaySubject
is a class that extends Subject
. Here's a simplified look at how it's structured:
export class ReplaySubject<T> extends Subject<T> {
constructor(
private _bufferSize = Infinity,
private _windowTime = Infinity,
private _timestampProvider: TimestampProvider = dateTimestampProvider
) {
super();
}
next(value: T): void {
// This method is overridden to buffer the emitted values
// and replay them to new subscribers based on the buffer size
}
}
The key difference lies in the overridden next()
method. It stores emitted values in memory and re-emits them to new subscribers — depending on the configured bufferSize
and windowTime
.
This makes ReplaySubject
perfect when you want late subscribers to catch up on a stream's most recent activity, rather than starting fresh.
🔚 Conclusion
That wraps up our deep dive into ReplaySubject
!
To summarize:
- It stores and replays multiple past values to new subscribers.
- No need for an initial value.
- Super useful when late subscribers need context.
Next up, we’ll explore AsyncSubject and see how it fits into the RxJS family.
💬 Got questions or use cases you want to share? Drop a comment below! Let's discuss more Angular magic. ✨
✍️ Author: Vetriselvan
👨💻 Frontend Developer | 💡 Code Enthusiast | 📚 Lifelong Learner | ✍️ Tech Blogger | 🌍 Freelance Developer
This content originally appeared on DEV Community and was authored by vetriselvan Panneerselvam

vetriselvan Panneerselvam | Sciencx (2025-06-29T14:47:36+00:00) Exploring ReplaySubject in RxJS: How to Replay Past Values in Angular. Retrieved from https://www.scien.cx/2025/06/29/exploring-replaysubject-in-rxjs-how-to-replay-past-values-in-angular/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.