In Angular applications preferred way for event handling or asynchronous programming is by using observables. Observables provide support for data sharing between publishers and subscribers.
So now one question should be raised: What is the meaning of publisher and subscriber?
Publishers are the one who publishes the data and Subscribers are the ones who consume the data.
Normally Subscription means an arrangement to receive something.
Similarly, in Angular applications Observables will be connected to observers and whenever they observe a new value or change in data, they will execute code with the help of Subscription and all the subscribed components will receive the updated outcome.
One note for observables is that a particular observable can be accessed by only those components which are subscribed to it.
Let’s start with the ways of handling Subscriptions:
Unsubscribe ():
When we subscribe to some observable to get a certain result once that component is getting destroyed along with that to cancel subscription is a good practice. With the help of the .unsubscribe () method subscribed subscriptions will be canceled/removed.
Example:
import {Component, OnInit, Output, EventEmitter, OnDestroy } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Subscription } from 'rxjs'; @Component({ … }) export class ExampleComponent implements OnInit, OnDestroy { data: any; private subscription: Subscription; API: string = 'https://jsonplaceholder.typicode.com/todos/1'; constructor (private http: HttpClient){} ngOnInit() { // Subscribed here this.subscription.add( this.http.get(this.API).subscribe( res => { this.data = res; } ); ) } ngOnDestroy() { // Unsubscribed the subscription this.subscription.unsubscribe(); } }
If there’s an array of subscriptions in a single component then we can destroy all the Subscriptions in the onDestroy method.
RxJS take* operators:
For unsubscribing the subscription following take operators can be used:
take(n): It makes subscription happen n number of times specified and completes it.
The preferred value for n is 1 so the subscription executes once and exits.
@Component ({…}) export class ExampleComponent implements OnInit { subscription$ ngOnInit () { const observable$ = rx.Observable.interval(100); // Here subscription will be emitting the result once on initialization and then will unsubscribe it. this.subscription$ = observable$.pipe(take (1)). subscribe (x => console.log(x)) } }
takeUntil(notifier): It emits the values by source until a notifier Observable emits a value.
Now, what exactly notifier means?
In simple words, it means some indicator that will indicate something. Similarly, in Angular, it means the Observable whose first emitted value will cause output Observable of takeUntil to stop emitting values from the source Observable.
Example:
@Component ({...}) export class ExampleComponent implements OnInit, OnDestroy { notifier = new Subject() ngOnInit () { const observable$ = rx.Observable.interval(100); observable$.pipe(takeUntil(this.notifier)).subscribe (x => console.log(x)); } ngOnDestroy() { this.notifier.next() this.notifier.complete() } }
In this example, takeUntil will emit values emitted by interval until notifier Subject emits, and after that It will unsubscribe observable$.
takeWhile(predicate): Emits value obtained by the source Observable till it satisfies the predicate which means certain state or condition and completes/unsubscribes as soon as the condition is not satisfied.
Example:
@Component({...}) export class ExampleComponent implements OnInit , OnDestroy{ ngOnInit () { var observable$ = rx.Observable.interval(100); observable$.pipe(takeWhile(value => value < 15)).subscribe (x => console.log(x)); } ngOnDestroy() { this.subscription$.unsubscribe() } }
So here it will emit the values as long as less than 15. If the value would be greater than 15 it will unsubscribe the observable$. And also if the component gets destroyed before all values are emitted it will cancel the subscription on ngOnDestroy().
Use Async pipe:
Here async pipe subscribes to Observable and returns the latest value that is emitted. Async pipe keeps checking for the updates in component and as component gets destroyed it automatically unsubscribes the subscription.
Example:
@Component({ ..., template: ` <div> Time: {{observable$ | async}} </div> ` }) export class ExampleComponent implements OnInit { observable$ ngOnInit () { this.observable$ = rx.Observable.interval(100); } }
Here async pipe will subscribe to the observable$ and display the emitted value and if the component gets destroyed async pipe will unsubscribe the observable$.
RxJS First Operator:
This operator is a combination of take(n) and takeWhile(predicate). So, by default, it emits the first value emitted by the Observable and if any predicate is specified it will return as per the condition.
Example 1:
@Component({...}) export class ExampleComponent implements OnInit { observable$ ngOnInit () { this.observable = rx.Observable.interval(100); // It will return the first value emitted and unsubscribe the observable$ this.observable$.pipe(first()).subscribe(x => console.log(x)); } }
Example2:
@Component({...}) export class AppComponent implements OnInit { observable$ ngOnInit () { this.observable$ = rx.Observable.interval(100); // It will emit the values if value would be less than 20, if it will exceed 20 it will unsubscribe automatically this.observable$.pipe(first(val => val > 20)).subscribe(x => console.log(x)); } }
So, the reason for handling subscription is that whenever any component is subscribed to any observable and if you switch the component in between of ongoing subscription it will destroy the component but subscription will not get canceled and that can result in memory leak issue or performance drop in application.
So, unsubscribing the subscription is a good practice for Angular applications.
Our team of experts will review your project and give you a quote at no cost.
In this episode of the The Lazy CEO Podcast,…
Join us for an enlightening episode of The CEO…
Creating multi-agent workflows is the future of AI development,…
How has sunflower lab's focus on integrating ai, data…
Businesses are quickly shifting towards optimized processes. And the…
Developers often make mistakes when using Power Automate, which…