How to Handle Subscriptions in Angular 10

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.  

What is a Subscription?  

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.  

How to handle Subscription?  

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();  

  }  

}
Get a quote on your project!

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)  
  • takeUntil(notifier)  
  • takeWhile(predicate)  

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.  

Example: 

@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));  

 }  

}

Conclusion:  

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.  

Get a FREE estimate for your project today.

Our team of experts will review your project and give you a quote at no cost.

Get a quote on your project!

Related Posts

From Vision to Action: Implementing AI & Automation

Planning your AI & Automation strategy is just the start (if you haven’t tackled Step 1 yet, check out our previous post to get caught up).…

Why is Databricks Lakehouse the Ultimate Data Solution for Your Company?

Businesses are forced to make compromises because of this conflict. Should they put more emphasis on performance and structure or on…

The First Step in Using AI & Automation for Productivity

When adopting AI and automation, taking the time to strategize ensures that your efforts and investment delivers fruitful results.