Rxjs Heaven ( Part 2: Subject, BehaviourSubject, ReplySubject )

Introduction 🚩 :

Hello Dear Readers

Making everything reactively is a trend in web development currently with the most famous JS frameworks not only with Angular! so I decided to start a series of blogs about Rxjs 🔥 (A reactive programming library) and cover the most use cases with code examples to help you clearly understand why I called Rxjs a Heaven ☀️

This series of blogs will contain :

RxJS brings a lot of great functionality into our Angular

  • Part1: Error Handling With Rxjs ( Done ✔️)
  • Part2: Multi-Casting Operators with Rxjs (Current blog ☑️)
  • Part3: Higher-order operators with Rxjs ( coming soon ⏳)
  • Part4: Custom operators with Rxjs ( coming soon ⏳)

Each part will contain an explanation for the operators, code _examples, and the most use cases for each one

Happy reading :)

Problem ⁉️:

During front-end implementation and while using these trading frameworks you will need to divide your page into small UI components

The more you divide it, the more the complexity growth and it will be a necessary requirement to communicate between these different components for example data exchange 🗂, synchronization between them, etc …

So how we can solve this communication requirement, know the different types of communications that should be implemented, and how we can guarantee synchronization also?

Solution: Rxjs Multi-casting operators ☑️

Rxjs provide for us quite powerful operators that are very helpful and can be used for different scenarios.

They can be used for one-way-casting (one point to another )and multi-casting (communication from one point to a group)

Otherwise, There are a lot of use-cases that we will need to ensure communication between components for example :

  • Authentication-Scenario: User Sign-In and notify Navbar-Component to render The sign-out menu-item
  • E-commerce-Application: adding an item from the product-details-component and notify the panel-counter to be changed
  • UI-implementations: Dispatching Actions to Close-Modal, Changing Tabs-Element and rendering each TabComponent, etc...
  • Real-Time Notifications, Chat Applications

I tried to list the use-cases that I met before and it can meet any other developer while dealing with complex UI and large applications (Angular Experience)

So to know how to deal with these kinds of situations , I will in the next section explain for you the common Rxjs operators ( Subject, BehaviourSubject, ReplySubject) that can be used as recommended operators.

- The RxJS Subject📖:

What is a Subject? An RxJS Subject is a special type of Observable that allows values to be multicasted to many Observers

So this operator is can be used to emit data in a multi-casting ➭ ➮way

For example✍ ️, as in the image below, we can have a Subject that will emit data (value=20) to all other ( components ) that subscribed to this subject

source: https://shrestharohit.com.np/subject-behavioursubject-rxjs-angular/

Use-Case 📘:

I will show you an example of Angular Component Messaging,

for an E-commerce App to interact between Product-component after being added to the cart and to be displayed in other components

For this kind of messaging, we will use the Subject operator

Code-Example 📘:

cart.service.ts

import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs';

@Injectable({ providedIn: 'root' })
export class CartService {
private subject = new Subject();

addToCart(product:string) {
this.subject.next({name:product});
}

clearCart() {
this.subject.next();
}

getCart(): Observable{
return this.subject.asObservable();
}
}

app.component.ts

import { Component, OnDestroy,OnInit } from '@angular/core';
import { Subscription } from 'rxjs';
import { CartService } from './cart.service';

@Component({
selector: 'app-root',
templateUrl: './app.component.html'
})

export class AppComponent implements OnDestroy {
subscription: Subscription;
cart: any;
products: any[] = [];
constructor(private cartService: CartService) {
// subscribe to product component
this.subscription = this.cartService.getCart().subscribe(product => {
if (product) {
this.products.push(product);
} else {
// clear product
this.products = [];
}
});
}

ngOnDestroy() {
// unsubscribe to ensure no memory leaks
this.subscription.unsubscribe();
}

}

product.component.ts

import { Component} from '@angular/core';

import { CartService } from '../cart.service';

@Component({
selector: 'app-home',
templateUrl: './product.component.html'
})
export class ProductComponent{
constructor(private cartService: CartService) {}

addToCart(): void {
// send product data to subscribers via observable subject
this.cartService.addToCart('Product item from Product Component to App Component');
}

clearCart(): void {
// clear cart
this.cartService.clearCart();
}
}

Code-Explanation 📘:

  1. We will define a Subject operator in our service card. service who will handle the logic of sending data between components.
  2. When we will click the button: add-to-cart defined with ProductComponent, we will emit data(new added-product) in a multi-casting way to all subscribers to this event.
  3. For our case, we have the AppComponent as a First-Subscriber to display the already emitted data.

- The RxJS BehaviourSubject📖:

BehaviorSubject is a specific type of Subject and requires an initial value while definition and will always give you the last emitted value right away.

// ********behaviour subject*********
// Behavior subjects need a first value
let subject1 = new BehaviorSubject<string>("First value");
source: http://reactivex.io/documentation/subject.html

BehaviorSubject vs Subject :

It will always return a value on subscription even if it hasn’t received a next()

BehaviorSubject Example :

// Behavior Subject

// a is an initial value. if there is a subscription
// after this, it would get "a" value immediately
let bSubject = new BehaviorSubject("a");

bSubject.next("b");

bSubject.subscribe(value => {
console.log("Subscription got", value); // Subscription got b,
// ^ This would not happen
// for a generic observable
// or generic subject by default
});

bSubject.next("c"); // Subscription got c
bSubject.next("d"); // Subscription got d

Subject Example :

// Regular Subject

let subject = new Subject();

subject.next("b");

subject.subscribe(value => {
console.log("Subscription got", value); // Subscription wont get
// anything at this point
});

subject.next("c"); // Subscription got c
subject.next("d"); // Subscription got d

For Subject is only triggered for values received after subscription,

for the example subject.next("b") ,it’s triggered before the subscription so nothing will be sent to the subscriber!

Use-Case 📘: User-authentication with BehavioourSubject in Agular

In this use case, I will show a real-world example of how to use BehaviourSubject to manage user-authentication actions (sign-in and sign-out) and the use of initial-value ( localStorage toke value ).

Code-Example 📘:

Code-Explanation 📘:

private loggedIn = new BehaviorSubject<boolean>(false);

Initialization default value =false because no currentUser is connected by default, so we will need an initial value that will be emitted for example to the Navbar Component ( to render NavbarSignIn- Component)

login(user) {    
if (user.email !== '' && user.password !== '' ) {
return this.server.reque
st('POST', '/login', {
email: user.email, password: user.password }).subscribe((response: any) => {
if (response.auth === true && response.token !== undefined)
{ this.token = response.token; this.server.setLoggedIn(true, this.token);
this.loggedIn.next(true);
const userData = {
token: this.token, };
  • this.loggedIn.next(true): will emit value true to all subscribers and notify them that there is a user connected
logout() {    this.server.setLoggedIn(false);  
delete this.token;
this.loggedIn.next(false);
localStorage.clear();
this.router.navigate(['/']);
}
  • this.loggedIn.next(false): notify all the subscribers that the user logged-out

- The RxJS ReplaySubject 📖:

The ReplaySubject will emit old values to new subscribers.

It can replay everything that was previously sent by just specifying a number,

Syntax :

import { ReplaySubject } from ‘rxjs’;
const subject = new ReplaySubject(3);
// buffer 3 values for new subscribers
source: http://reactivex.io/documentation/subject.html

Use-Case-Example 📘:

It can be used to track history, for example, it can be used to tracking the history record of chat applications in real-time

Differences with BehaviorSubject ❗️:

ReplaySubject will replay values, even after observing an error, where BehaviorSubject will not

Code-Example 📘:

Code-Explanation 📘:

As mentioned in the comments with the source code, when we will subscribe to our ReplySubject, we will get the last n=3 (defined params) emitted values.

-References 📓 📕 :

Conclusion ❤️👏:

In conclusion, I tried to show you the mostly communication Rxjs operators ( Subject(),BehaviourSubject() , ReplySubject()) with some code examples and explanation .

I hope it helps and you enjoyed it 😀

If you liked this post feel free to leave a 👏, and follow me on Twitter and Github

Thanks 🙂

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store