DEV Community

Cover image for RxJS 7 - Subjects
Barış BALLI
Barış BALLI

Posted on

RxJS 7 - Subjects

Here are my detailed notes from the fantastic course created by Jurek Wozniak, called RxJS 7 and Observables: Introduction.

In order to understand the concept please consider buying the course yourself, these notes are simply subsidiaries

Subjects

Subjects allow us to multicast notifications to multiple observers, because of it is using a shared resource, it is a hot observable.

Subjects work like event emitters, they emit events and all the observers that are subscribed to it, react to those multicasted events.

Subjects has 2 natures: observable and observer. They can be subscribe-able like normal observables. But at the same time can be used .next() .error() and .complete() like an observer.

Subjects in Action

import { fromEvent, Subject } from 'rxjs';
import { map } from 'rxjs/operators';

const emitButton = document.querySelector('button#emit');
const inputElement: HTMLInputElement = document.querySelector('#value-input');
const subscribeButton = document.querySelector('button#subscribe');

const value$ = new Subject<string>();

fromEvent(emitButton, 'click').subscribe(() => value$.next(inputElement.value));

fromEvent(subscribeButton, 'click').subscribe(() => {
  console.log('New Subscription');
  value$.subscribe((value) => console.log(value));
});
Enter fullscreen mode Exit fullscreen mode

Image shows console print to prove the concept

After we subscribe we could emit to multiple observers.

We could also emit a value directly by passing the subject, there is no need to specifically call next in subject.

fromEvent(emitButton, 'click')
  .pipe(map(() => inputElement.value))
  .subscribe(value$);
Enter fullscreen mode Exit fullscreen mode

BehaviourSubject - Concept

Let’s say we have a subject and 2 observers,

Subject is emitting match scores and 2 observers since they followed the match since the beginning know the score (2:1).

Let’s say we have one more observer that has joined, the new observer will not have an opportunity to know the score until a new notification is emitted.

In order to solve this there is another subject type called BehaviourSubject, this subject emits the latest notification to the newly joined observers, when they join.

import { BehaviorSubject, fromEvent, Subject } from "rxjs";
import { withLatestFrom } from "rxjs/operators";

const loggedInSpan: HTMLElement = document.querySelector('span#logged-in');
const loginButton: HTMLElement = document.querySelector('button#login');
const logoutButton: HTMLElement = document.querySelector('button#logout');
const printStateButton: HTMLElement = document.querySelector('button#print-state');

const isLoggedIn$ = new BehaviorSubject<boolean>(false);

fromEvent(loginButton, 'click').subscribe(() => isLoggedIn$.next(true));
fromEvent(logoutButton, 'click').subscribe(() => isLoggedIn$.next(false));

// Navigation bar
isLoggedIn$.subscribe(
  isLoggedIn => loggedInSpan.innerText = isLoggedIn.toString()
);

// Buttons
isLoggedIn$.subscribe(isLoggedIn => {
  logoutButton.style.display = isLoggedIn ? 'block' : 'none';
  loginButton.style.display = !isLoggedIn ? 'block' : 'none';
});

fromEvent(printStateButton, 'click').pipe(
  withLatestFrom(isLoggedIn$)
).subscribe(
  ([event, isLoggedIn]) => console.log('User is logged in:', isLoggedIn)
);
Enter fullscreen mode Exit fullscreen mode

Image shows console print to prove the concept

We see that for the BehaviourSubjects we need to provide an initial value

Let's keep in touch

Hey, thanks a lot if you read it so far.
I want you to keep in touch for more sweet content.
Please subscibe in Dev.to and other channels (🦸‍♂️ especially twitter)

Twitter 🐦 https://twitter.com/barisbll_dev
Linkedin 📎 https://www.linkedin.com/in/barisbll-dev/
Github 👨🏻‍💻 https://github.com/barisbll
Medium 📰 https://medium.com/@barisbll

Top comments (0)