UI Development

My Fun with Angular Observables

I have one lazy friend, his name is Observablewho responds only when somebody subscribes to him. He has wide variety of information (multiple values) with him but he strictly decides when to push the information to his subscribers with three options namely next for values, error for exception / error and complete is for stopping to push the values. His condition is that, the subscriber can call next any number of times but he goes back to sleep upon calling either error or complete, no more values will be pushed to the subscriber. What a strict protocol my friend has !!!

My lazy and strict friend is generous too, he does not mind if somebody wants to cancel the subscription through unsubscribe() method. Thanks for his generosity but who am I ? I am  Angular, Oh, Ok!!!

Let me introduce you one of my old friend Promise, who is too eager to push the information and is good friend of mine before I met Observable. Even if somebody does not consume the information, the very eager Promise friend pushes the information to the subscriber (by the way I use then here) and is a very straight forward person, either resolve or reject in pushing the data, that’s it. I started my friendship with Promise to eliminate the call back hell (yeah! you are right, I mean Pyramid of Doom).

Let me share some sample code, how I enjoyed my friend ship with Promise.

let promise = new Promise(function(resolve, reject) {
  /* some how isReady becomes true here */
   if (isReady) {
    resolve("Push the content!");
  }
  else {
    reject(Error("I am lost"));
  }
});
promise.then(function(result) {
  console.log(result); // "Push the content!"
}, function(err) {
  console.log(err); // Error: "I am lost"
});

But soon, he started troubling me, because he can’t send multiple values and by default he does not allow me to cancel. If at all, I want to cancel the Promise then he gives a rude answer to go and bang with setInterval and clearInterval , otherwise barrow / steal from Bluebird !!!. Even ES6 has shown official red card for this proposal to support cancel option for Promise,  Alas!!!. In addition to these irritations, as I became more inclined towards reactive programming style, I felt the need to find a new friend and say bye to my old friend Promise, even though occasionally, still I remember him . That is when my lazy friend Observable came for rescue.

Before going to back to Observable , you might be surprised what is this pushpushpush, … which is common in both friends Promise and Observable. Is there any pull too? Ok, let me tell what is this, push and pull fight. These are the two different protocols used to decide how the data producer should communicate with data consumer. For example, in case of functions, the function is a data Producer and the code that calls the function is consuming the data given by the producer by “pulling” out a single return value from its call.

Refer the below for better clarity ( http://reactivex.io/rxjs/manual/overview.html )

Single Multiple
Pull Function Iterator
Push Promise Observable

Let’s now, come back to our Observable, in normal way I feel, it is little clumsy to work with my Observable friend because the core concerns that bothers me are like Creating, Subscribing, Executing and Disposing Observable. But I found an easier way to work with all these through RxJS . By this RxJS, I can easily create Observable and use subscribe / unsubscribe methods for subscribing and disposing Observable. I even get nice pizza, ice cream, cake, etc readily available for me to eat based on my hunger and taste bud needs, during the execution phase!!!.  Don’t get scared,  I mean, many operators like mapswitchMapdebounceTimedistinctUntilChanged, etc and many other exciting ready to eat operators are available for me to use through RxJS.

Let me share some sample code of these below:

import {Component} from '@angular/core';
import {Observable} from 'rxjs/Observable';
.......
.......

export class MyFunObservables {

  private myObservable: Observable<Array<string>>;
  private names: Array<string> = [];
  private isError: boolean;
  private isComplete: boolean;
  private mySubscription: Subscription;


  constructor() {
  }

  ngOnInit() {
      this.myObservable = new Observable(observer => {
      
          setTimeout(() => {
              observer.next('Gopal');
          }, 500);

          setTimeout(() => {
              observer.next('Venkat');
          }, 750);
          
         setTimeout(() => {
              observer.error(new Error('UnExpected Error!'));
          }, 1000);
          
          setTimeout(() => {
              observer.complete();
          }, 1250);
      });

       this.mySubscription = this.myObservable.subscribe(
          value => this.names.push(value),
          error => this.isError = true,
          () => this.isComplete = true
      );
  }

ngOnDestroy() {
    this.mySubscription.unsubscribe();
  }
}

I work extensively with Observable in Http ModuleForms ModuleRouting Module and in Event Emitters. As you all know, I have html and class files in my components, so I have provided couple of different approaches to use the data values from Observables. In templates (html), the option is to use async pipe in which I automatically handle the subscription during the component life cycle. So the subscribe and unsubscribe will happen automatically but I need Common Module to be imported.  One problem here is,  I will not be able to manipulate the values from the Observable before using them. For that I need to go for another method subscribe() in my component class. The sad part here is, unsubscribe() needs to be done manually. If somebody forgets it, then it is a performance hit .

Let me share some sample code snippets on these .

Http Module : httpClient is returning an Observable,

public ngOnInit() {
        this.employees$ = this.httpClient.getEmployees();
    }

using async pipe,

<ul class="emploee_details" *ngIf="(employees$ | async).length">
    <li class="employee" *ngFor="let emp of employees$ | async">
        {{ emp.name }} - {{ emp.role }}
    </li>
</ul>

using subscribe method,

public ngOnInit() {
        this.httpClient.getEmployees().subscribe((employees: IEmployee[]) => 
            this.employees = employees
        })
    }

Routing Module : Route params through ActivatedRoute, which gives the dynamic access to the updated routing param values using Observables, without the need for reloading the current component.

import {Component} from '@angular/core';
import {ActivatedRoute, Params} from '@angular/router';

.......
.......

export class EmpDetailsComponent {
  emp : {id: number, name : string};
  
  constructor(private route: ActivatedRoute) { }

  ngOnInit() {
      this.route.params
        .subscribe(
        (params: Params) => {
            this.emp.id = params['id];
            this.emp.name = params['name'];
          }
        )
  }

}

In Reactive FormsObservables are present in FormControl properties like valueChanges and statusChanges to raise change events. Similarly in EventEmitter for component communication, I heavily depend on my Observable friend.

Conclusion : Here is an effort is made to explain the concept of Observables and their role in Angular in common terminology so that even a beginner will be able to get the features of Observable and how they differ from Promises and their use cases in Angular. And also the relevance of RxJs in these. In future, I will explore each one of these Angular use cases in greater detail.

It seems my Observable friend started worrying now, thinking when his friendship will also be cut off similar to Promises. Time and Tide waits for none. Let’s wait and see, what future decides.

About The Author