An observable in RxJS is similar to a subject. In basic terms, an RxJS subject is a unique observable that may multicast or communicate with many observers.
According to its definition, “A subject is similar to an observable, except that it can multicast to several observers. Subjects are similar to EventEmitters in that they keep track of a large number of listeners.”
Subscribing to an RxJS topic is similar to subscribing to an observable. It also includes methods like next(), error(), and complete(), which we see and utilize in our observable construction function.
Every observable has a subject. We may link to a given subject in the same way that we subscribe to an observable, and it will typically begin receiving values. It’s impossible to tell if the observable implementation is coming from a simple unicast subject or from the observer’s perspective.
The most significant distinction between a subject and an observable is that a simple observable is unicast by default. This means that each subscribing observer has its own observable execution. Subjects, on the other hand, can be broadcast to several audiences. A subject is similar to an observable, except that it may broadcast to a large number of observers. Multicasting is the primary purpose for utilizing subjects.
Consider the following observable example –
1
2
3
4
5
6
7
8
9
10
11
12
import * as rxjs from "rxjs";
const observable = rxjs.Observable.create((obs) => {
obs.next(Math.random());
});
// Subscription-1
observable.subscribe((obsData) => {
console.log(obsData);
});
// Subscription-2
observable.subscribe((obsData) => {
console.log(obsData);
});
We’ll get the following result if we run the previous example. Because observables are designed to be unicast, they will provide different random outcomes each time you run the preceding example. Take a look at the output.
Every time we run the application, the output is unique for both subscribers, as you can see. If you want each subscriber to receive identical values, this isn’t very nice. Because subjects can multicast, they are employed to solve this problem. It indicates that several subscribers share a single observable execution.
EventEmitters are similar to subjects in that they’re used to keep track of a large number of listeners. So, calling subscribe on a subject doesn’t start a new execution, it just adds the specified observer to a collection of observers.
Let’s look at how to utilize subjects to multicast and solve the above-mentioned problem.
1
2
3
4
5
6
7
8
9
10
11
12
13
import {
Subject
} from "rxjs";
const sub = new Subject();
// Subscription-1
sub.subscribe((subData) => {
console.log(subData);
});
// Subscription-2
sub.subscribe((subData) => {
console.log(subData);
});
We’ll get the following output in our terminal window after executing the above piece of code –
You can see that the code generates different random numbers each time we run it, yet the values passed to both subscriptions are equal. It indicates that both subscriptions are receiving the same piece of data.
We need to import Subject from rxjs library in order to work with an RxJS subject in the following way:
import { Subject } from "rxjs";
Now, we can create an object of the subject by the given piece of code–
const subject = new Subject();
As RxJS Observables has three methods, similarly Subjects also comes with three methods –
next(v) – passing to the next subscription by returning the value “v”.
error() - throwing the error in the middle of the subscription.
complete() - indicates the successful completion in the middle of the subscription.
We must subscribe to the RxJS subject after it has been created. A subscription is a type of object that is used to portray a reusable resource, generally the execution of the subject. Using the following method we can simply create numerous subscribers on the subject.
1
2
3
4
5
6
subject.subscribe({
next: (value) => console.log(`From subject - {value}`)
});
subject.subscribe({
next: (value) => console.log(`From subject - {value}`)
});
We need to pass data to the subject we create after subscribing to it. This can be done by using the next() method in the following way –
subject.next("VALUE")
The data “VALUE” is used to pass to all subscription objects of the subject it is subscribed to. Below we will see the implementation of the subject in which we’ll learn how to use all three methods.
Example representing the use of next(v) method:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import {
Subject
} from "rxjs";
const subject = new Subject();
subject.subscribe({
next: (value) => console.log(`From subject - {value}`)
});
subject.subscribe({
next: (value) => console.log(`From subject - {value}`)
});
subject.next("Hello World!")
subject.next("I'm RxJS Subject")
Here, we create an instance of the subject class as “subject” by calling new Subject() and give reference to the next() method. The output of the above example is given below.
Example representing the use of complete() method:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import {
Subject
} from "rxjs";
const subject = new Subject();
subject.subscribe({
next: (value) => console.log(`From subject - {value}`)
});
subject.subscribe({
next: (value) => console.log(`From subject - {value}`)
});
subject.next("Hello World!")
subject.complete()
subject.next("I'm RxJS Subject") // IGNORED
Output –
Here you can see that complete() acts as the break of an ongoing subscription. All references passed by next() method ahead of complete invocation are ignored (you can see that the subject with value “I’m RxJS Subject” is not printed on the terminal).
Example using error() method; this is used to throw an error to the console.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import {
Subject
} from "rxjs";
const subject = new Subject();
subject.subscribe({
next: (value) => console.log(`From subject - {value}`)
});
subject.subscribe({
next: (value) => console.log(`From subject - {value}`)
});
subject.error(new Error("There is an error!"))
Output –