Explain Codes LogoExplain Codes Logo

Subject vs BehaviorSubject vs ReplaySubject in Angular

javascript
subject-engineering
angular
state-management
Anton ShumikhinbyAnton Shumikhin·Aug 29, 2024
TLDR

A Subject is a multicaster broadcasting to multiple observers. Perfect for when subscribers show up to the party exactly on time to hear real-time updates.

In contrast, a BehaviorSubject needs an initial value on signup and generously re-emits the last announced data to new participants. Ideal for a snapshot of the "current state" data.

Lastly, a timeless ReplaySubject replays old conversations (just the most relevant ones per your specifications, of course) to any late joiners, providing bits from the past on a platter.

Snippets for your delight:

// Subject: only sends values to those already listening (no FOMO). let subject = new Subject(); subject.next(1); subject.subscribe(console.log); // Completely misses awkward zero, gets 2: phew! // BehaviorSubject: hands last value to anyone who asks, always. let behaviorSubject = new BehaviorSubject(1); behaviorSubject.subscribe(console.log); // Gets 1, no questions asked! behaviorSubject.next(2); // And here's a 2 for you! // ReplaySubject: passionately rekindles old moments buffered just for you! let replaySubject = new ReplaySubject(2); replaySubject.next(1); replaySubject.next(2); replaySubject.subscribe(console.log); // Gets the full story, 1 and 2!

Your cheat sheet:

  • Use Subject for data that won't be on any history tab.
  • Grab BehaviorSubject for easy access to the latest news.
  • Opt for ReplaySubject when you need to rewind time on record.

An in-depth look with use cases

Handling routing and state management with BehaviorSubject

An overachiever BehaviorSubject shines in Angular for state management and routing guards— it comes in handy when you can't survive without knowing the current state. It promises to deliver the most recent valid state to its consumers.

// AppState, a shiny BehaviorSubject, always up-to-date const appState = new BehaviorSubject(getInitialState()); appState.subscribe(state => { // The stale state-gone-dates? Never been there! // Always gets the most recent state, here's your ticket to real-time data. }); appState.next(newState());

Using ReplaySubject for historical data needs

ReplaySubject is your private investigator in applications needing full or partial data history, like chat services. You control how far your investigator looks back at the past with a customizable buffer size.

// Imagine a chat history, ReplaySubject on the job! const chatHistory = new ReplaySubject(100); chatHistory.subscribe(messages => { // Gets to live past 100 messages, your personal time machine. }); chatHistory.next(newMessage());

Real-time events and the Subject

Events such as clicks and form submissions? Your trusty Subject has got you covered. No need for a past diary, a Subject helps subscribers tap into real-time events from the moment they tuned in.

// Form submission with Subject, handles events like a boss const formSubmit = new Subject(); formSubmit.subscribe(action => { // No more late news, fast and current form submission events only }); formSubmit.next(submitEvent());

Critical differences and effects

The subscription timing game and value emission contest

When you sign up for social media (our Subject types here) impacts how much of the feed you get to see:

  • With a Subject, late-comers have missed all the past posts.
  • BehaviorSubject shows you the last-n-coolest post, for immediate indulgence in the current trend.
  • ReplaySubject takes you through the memory lane, showing several posts depending on just how nostalgic it's set to be (buffer size).

Buffer size, system resources and your sanity

Going overboard with ReplaySubject buffer sizes might consume resources faster than you can say "memory leak!" Be a smart data keeper, especially when maintaining large datasets or running complex applications.

Afterparty bonus: subject completion and what follows

A done-and-dusted ReplaySubject is your kind mate who saves the best party gossips (buffered values) even after the party ends. A finished BehaviorSubject, however, isn't that generous - no reprints of past drama once the session is over.

Usage hacks for Subject types

Pattern matching with buffer size

Keep your buffer size relevant to your app's scenario. ReplaySubject of size 1 is your new BehaviorSubject, or you can hold a bigger window to the past.

No memory leak mishaps

Do not forget to dispose of your subscriptions properly. Angular’s lifecycle hooks, ngOnDestroy, or operators like takeUntil or takeWhile are here to save the day from memory leaks.

Subject swapping on the go

You can convert between subjects. For instance, when you realize your Subject has to step up and maintain a last emitted value, a simple makeover to a BehaviorSubject has got you covered.