Observable
Observable, also known as ReactiveX library, comes from RxJS and itās really useful to handle events, and, more particularly, to subscribe to them. As an example, Angular uses observables as an interface for its core functionalities such as:
-
Define custom events to send outputs data from child component to parent component.
-
Handle AJAX requests and responses through HTTP modules.
-
Listen and respond to user-input events in the Angular Router and Form modules.
In Angular, RxJS provides 4 types of subjects to create an observable. Those 4 types are Subject, BehaviorSubject, ReplaySubject and AsyncSubject. They can be distinguished from each other by looking at how they react to subscribe. But, in this article, we are going to discuss the way of implementing the BehaviorSubject which is one of the most common subjects in Angular.
BehaviorSubject
First of all, you need to have basic knowledge of how the Subject works. When you subscribe to the Subject, you will get every event emitted from the Subject after you subscribed to it. Refer to this video.
But in the BehaviorSubject, it seems to work same as the Subject, except it receives the last event that occurred before the subscription. Refer to this video.
So, there are few reasons to prefer the BehaviorSubject over the Subject:
-
It will always return the current value on subscription (Require initial value when initialization).
-
It has a
getValue()
function to get the current value. -
It ensures that the component always receives the most recent data.
We can illustrate the implementation of BehaviorSubject by using the example of data sharing between components.
First of all, we need to create a service using a private BehaviorSubject that will hold the current value of the message. We define a currentMessage variable to handle this data stream as an observable that will be used by the components. After that, we implement a function to call the next()
function to change its value.
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Injectable()
export class DataService {
private messageSource = new BehaviorSubject('default message');
currentMessage = this.messageSource.asObservable();
constructor() { }
changeMessage(message: string) {
this.messageSource.next(message)
}
}
Next, letās see how we can use this DataService inside both parent and child components.
In the parent component, inject the DataService in the constructor. Then subscribe to the currentMessage observable of the DataService to get value changes.
import { Component, OnInit } from '@angular/core';
import { DataService } from "../data.service";
import { Subscription } from 'rxjs';
@Component({
selector: 'app-parent',
template: `
{{message}}
`,
styleUrls: ['./sibling.component.css']
})
export class ParentComponent implements OnInit, OnDestroy {
message:string;
subscription: Subscription;
constructor(private data: DataService) { }
ngOnInit() {
this.subscription = this.data.currentMessage.subscribe(message => this.message = message)
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
Then, we create a changeMessage function inside the child component to assign a new value to the message. The important thing is, we can create a function in any component to change the message and it will automatically broadcast to all other components who are subscribed to the DataService.
import { Component, OnInit } from '@angular/core';
import { DataService } from "../data.service";
import { Subscription } from 'rxjs';
@Component({
selector: 'app-sibling',
template: `
{{message}}
<button (click)="changeMessage()">New Message</button>
`,
styleUrls: ['./sibling.component.css']
})
export class SiblingComponent implements OnInit, OnDestroy {
message:string;
subscription: Subscription;
constructor(private data: DataService) { }
ngOnInit() {
this.subscription = this.data.currentMessage.subscribe(message => this.message = message)
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
changeMessage() {
this.data.changeMessage("Hello this is the new Message")
}
}
In the above code snippet, after the user clicks the New Message button, the changeMessage function is triggered and the currentMessage observable updates its value from the new value of the message through the next()
function. Therefore, the parent component who is subscribed will receive the new message value. Also, not only the parent but also child, and sibling components who are subscribed receive the same treatment.
BehaviorSubject is a very simple, easy to use, but powerful way of creating a observable. I hope this article will help you get a basic understanding of BehaviorSubject.