How to use RxJS observables in Angular? How to subscribe services with reactive programming

RxJS is a library for reactive programming, RxJS stands for reactive extension for JavaScript. It helps to handle asynchronous request in a easier way using observables.

You must be thinking what is reactive programming, lets discus this.

Reactive programming

Reactive programming is based on observer patterns and it is basically used to handle asynchronous data streams.

Any event occurring can be defined as a data streams for example notification, messages etc.

Observer Pattern

Observer Pattern on the other hand is like a subscription system, if you have notice this, there are some website which ask for subscribing so that later they can send emails and notifications to you.

So there are publisher & subscribers. whenever publisher make any changes it notifies to subscribers, so to get any update from publisher you need to subscribe it. This is basically a observer pattern.

Two most commonly used terms in RxJS are observables and observer, lets understand what these terms means.

Observables

Observables are the data request and streams those notifies the observer to changes.

Observer

Observer consume these streams of data emitted from the observables.

Promise & Observables

Promise

In angular we have other ways to handle a asynchronous operations, and for that we can use promise. Promise use callbacks in async functions executions.

Problem with promise is that, its only emit one value at a time, it could be resolve or reject.

Promise are passive compared to observable that mean we cannot cancel promise once it started.

Like observables promise doesn’t have operators to handle operations on data.

Observables

On the other hand observables allow us to handle asynchronous and synchronous both operations. observables emits multiple values.

Observables are cancelable also, so you can cancel subscription of observables or service at any time you need.

Best thing about observables is, it has a lot of operators which can help to simplify our calculations.

Some of the commonly used operators are :

map(), retry(), tap(), filter(), reduce() etc.

Now let’s understand how you can use different patterns to subscribe and unsubscribe the services.

Imperative Unsubscribing Method

In this method we are subscribing to a method defined inside the service file. We are creating a subscription variable which can be used to unsubscribe this service on ngOnDestroy() method execution.

ngOnDestroy() works when someone move from one component to another component by the help of routing.

export class AppComponent {
  subscription: any;
  constructor(private service:ApiserviceService)
  ngOnInit(){
    //subscribing to the service
    this.subscription = this.service.getAllRecords().subscribe((result:any)=>{
      this.resultResponse = result;
    })
  }
  //unsubscribing the subscription
  ngOnDestroy(): void {
    this.subscription.unsubscribe();
  }
}

This is the classic method to subscribe and unsubscribe a service.

Declarative unsubscribing Method

This approach can be useful to unsubscribe multiple service with just one variable, and you can also use operators in this case, for this example we are using takeUntil operator, which manage the subscriptions state, it only destroy when component get destroyed.

import { Component } from '@angular/core';
import { ApiserviceService } from './services/apiservice.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  subscription$: any;
  constructor(private service:ApiserviceService)
  ngOnInit(){
    //subscribing to the service
    this.service.getAllRecords()
    .pipe(takeUntil(this.subscription$))
    .subscribe((result:any)=>{
      this.resultResponse = result;
    })
  }

  //unsubscribing the subscription
  ngOnDestroy(): void {
    this.subscription.next();
    this.subscription.complete();
  }
}

Declarative approach is better than imperative approach.

There is one more way which can be used for accessing data and displaying it on html page, but this method will not use any subscription for accessing data.

We can directly get data through observable without subscribing to any service, and by this method there is no need of unsubscribing also.

In this method we will use Async Pipe on html file and to access data we will create a observable which can access the another observable that is getting service response. In service file we normally call service through a function and return it to the variable which subscribe it.

//getting data from a api source
getAllRecords(){
    return this.http.get("http://apiurl.com");
}

Inside typescript or .ts file we use this by subscribing it, similar to the previous code.

Now inside the service file instead for creating a method or function we assign this api response to a observable and that observable we can use in component’s .ts file.

serviceResponse$ = this.http.get("http://apiurl.com");

Inside the service file now we can do this, we assigning api response to a observable, in the below code we are accessing this observable data by another observable of component’s .ts file.

  responseData$ = this.service.serviceResponse$;

serviceResponse$ and responseData$ are just observables you can name those anything, but don’t forget to use $ sign at the end, this is standard way to define observables to make code easy to read.

now responseData$ is a observable and we can not use it directly into the html, so now we will use async pipe to display this data using a *ngIf and *ngFor directives.

<ul *ngIf="responseData$ | async as responseData">
  <li *ngFor="let item of responseData">

  </li>
</ul>

By using this method you don’t need to subscribe the service, it will get the data and display on html page without subscribing. subscribing is also unnecessary, if there is no need try to avoid it.

If you like this blog please share it and also comment if you have any doubt. 🙂 Happy Coding.

Related Posts

3 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

×