Subjects In Angular
In this article, we will learn about RxJs Subjects in Angular. Subjects are unique observable that serves as both an observer and an observable. They allow us to use the next method to emit new values to the observable stream. Subscribers to the subject will receive the same instance of the subject and, as a result, the same values. We'll also demonstrate the distinction between observable and subject. If you're not sure what an observable is, check out our angular lesson on what it is.
What are the Subjects?
A Subject is a type of Observable that permits values to be broadcast to a large number of observers. Subjects are also observers because they can subscribe to another observable and derive value from it, which will be broadcast to all of its subscribers.
In essence, a subject can function as both an observer and an observable.
How do Subjects work
The subscribe method, as well as the next, error, and complete methods, are all implemented by subjects. It also keeps track of a group of observers[]
The Subject can be subscribed to by an Observer, who will benefit from it. They are added to the Subject's collection of observers. The stream alerts all of its Observers whenever a value is added to it.
The next, error and complete methods are likewise implemented by the Subject. As a result, it can subscribe to and receive data from another observable.
Creating a Subject in Angular
The code below demonstrates how to make an Angular subject.
Add the following code under the app.component.ts:
import { Component, VERSION } from "@angular/core"; import { Subject } from "rxjs"; @Component({ selector: "my-app", templateUrl: "./app.component.html", styleUrls: ["./app.component.css"] }) export class AppComponent { subject$ = new Subject(); ngOnInit() { this.subject$.subscribe(val => { console.log(val); }); this.subject$.next("1"); this.subject$.next("2"); this.subject$.complete(); } }
subject$ = new Subject();
We subscribe to it in the same way that we subscribe to any other observable.
this.subject$.subscribe(val => { console.log(val); });
The subjects have the ability to emit values. To send the value to its subscribers, use the next procedure. To get complete and error notifications, use the complete and error technique.
this.subject$.next("1"); this.subject$.next("2"); this.subject$.complete(); //this.subject$.error("error")
The subject is an Observable
this.subject$.next("1"); this.subject$.next("2");
The subject is hot Observable
Cold observable
import { Component, VERSION } from "@angular/core"; import { Subject, of } from "rxjs"; import { Component, VERSION } from "@angular/core"; import { Observable, of } from "rxjs"; @Component({ selector: "my-app", templateUrl: "./app.component.html", styleUrls: ["./app.component.css"] }) export class AppComponent { obs1$ = of(1, 2, 3, 4); obs$ = new Observable(observer => { console.log("Observable starts"); observer.next("1"); observer.next("2"); observer.next("3"); observer.next("4"); observer.next("5"); }); ngOnInit() { this.obs$.subscribe(val => { console.log(val); }); } }
obs1$ = of(1, 2, 3, 4);
Hot observable
import { Component, VERSION } from "@angular/core"; import { Subject } from "rxjs"; @Component({ selector: "my-app", templateUrl: "./app.component.html", styleUrls: ["./app.component.css"] }) export class AppComponent { subject$ = new Subject(); ngOnInit() { this.subject$.next("1"); this.subject$.next("2"); this.subject$.complete(); } }
Consider the following scenario. Because the subscription occurs after the subjects emit values, values 1 and 2 are lost.
import { Component, VERSION } from "@angular/core"; import { Subject } from "rxjs"; @Component({ selector: "my-app", templateUrl: "./app.component.html", styleUrls: ["./app.component.css"] }) export class AppComponent { subject$ = new Subject(); ngOnInit() { this.subject$.next("1"); this.subject$.next("2"); this.subject$.subscribe(val => { console.log(val); }); this.subject$.next("3"); this.subject$.complete(); } }
Every Subject is an Observer
import { Component, VERSION } from "@angular/core"; import { Observable, Subject } from "rxjs"; @Component({ selector: "my-app", templateUrl: "./app.component.html", styleUrls: ["./app.component.css"] }) export class AppComponent { subject$ = new Subject(); observable = new Observable(observer => { observer.next("first"); observer.next("second"); observer.error("error"); }); ngOnInit() { this.subject$.subscribe(val => { console.log(val); }); this.observable.subscribe(this.subject$); } }
this.observable.subscribe(this.subject$);
Subjects are Multicast
Multicast vs Unicast
import { Component, VERSION } from "@angular/core"; import { from, Observable, of, Subject } from "rxjs"; @Component({ selector: "my-app", templateUrl: "./app.component.html", styleUrls: ["./app.component.css"] }) export class AppComponent { observable$ = new Observable<number>(subscriber => { subscriber.next(Math.floor(Math.random() * 200) + 1); }); subject$ = new Subject(); ngOnInit() { this.observable$.subscribe(val => { console.log("Obs1 :" + val); }); this.observable$.subscribe(val => { console.log("Obs2 :" + val); }); this.subject$.subscribe(val => { console.log("Sub1 " + val); }); this.subject$.subscribe(val => { console.log("Sub2 " + val); }); this.subject$.next(Math.floor(Math.random() * 200) + 1); } }
The observable is subscribed by two people. Both of these customers will receive different amounts of money. Because observable on subscription creates a new instance of the producer, this is the case. As a result, each will be assigned a unique random number.
this.observable$.subscribe(val => { console.log("Obs1 :" + val); }); this.observable$.subscribe(val => { console.log("Obs2 :" + val); });
We then add two new subscribers to the subject. The random number is used by the subject to emit the value. Both subscribers receive the same value in this case.
this.subject$.subscribe(val => { console.log("Sub1 " + val); }); this.subject$.subscribe(val => { console.log("Sub2 " + val); }); this.subject$.next(Math.floor(Math.random() * 200) + 1);
Subjects maintain a list of subscribers
There are other types of subjects
- ReplaySubject
- BehaviorSubject
- AsyncSubject