RxJS 7 - Subjects
Tags: webdev, javascript, rxjs, angular
Published: 2023-04-06 08:11:22

_Here are my detailed notes from the fantastic course created by Jurek Wozniak, called [RxJS 7 and Observables: Introduction](https://www.udemy.com/course/rxjs-and-observables/)._

_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

```tsx
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));
});
```

![Image shows console print to prove the concept](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uecp5j8a0x3p14667w7t.png)



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.

```tsx
fromEvent(emitButton, 'click')
  .pipe(map(() => inputElement.value))
  .subscribe(value$);
```

## 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.

```tsx
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)
);
```

![Image shows console print to prove the concept](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/shuf0qswf9cxo33w0hl2.png)

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