w3resource

Practical Usage

A programming paradigm that cannot solve a real-world problem quickly thrown away, so in this tutorial we will look at some examples of using observables to solve real-world problems.

While building a real project there needs to be a communication between components, The way to communicate between components is to use an Observable and a Subject (which is a type of observable). Two methods we are interested in are: Observable.subscribe() and Subject.next().

Observable.subscribe()

The observable subscribe method is used by angular components to subscribe to messages that are sent to an observable.

Subject.next()

The subject next method is used to send messages to an observable which are then sent to all angular components that are subscribers (a.k.a. observers) of that observable.

Type-ahead suggestions

Observables can simplify the implementation of type-ahead suggestions. Typically, a type-ahead has to do a series of separate tasks:

  • Listen for data from an input.
  • Trim the value (remove whitespace) and make sure it’s a minimum length.
  • Debounce (so as not to send off API requests for every keystroke, but instead wait for a break in keystrokes).
  • Don’t send a request if the value stays the same (rapidly hit a character, then backspace, for instance).
  • Cancel ongoing AJAX requests if their results will be invalidated by the updated results.

Writing this in full JavaScript can be quite involved. With observables, you can use a simple series of RxJS operators:

type-ahead.ts

TypeScript Code:

import { fromEvent } from 'rxjs';
import { ajax } from 'rxjs/ajax';
import { map, filter, debounceTime, distinctUntilChanged, switchMap } from 'rxjs/operators';

const searchBox = document.getElementById('search-box');

const typeahead = fromEvent(searchBox, 'input').pipe(
  map((e: KeyboardEvent) => e.target.value),
  filter(text => text.length > 2),
  debounceTime(10),
  distinctUntilChanged(),
  switchMap(() => ajax('/api/endpoint'))
);

typeahead.subscribe(data => {
 // Handle the data from the API
});

Live Demo:

It is just a code snippet explaining a particular concept and may not have any output

See the Pen type_Ahead by w3resource (@w3resource) on CodePen.


Exponential backoff

Exponential backoff is a technique in which you retry an API after failure, making the time in between retries longer after each consecutive failure, with a maximum number of retries after which the request is considered to have failed. This can be quite complex to implement with promises and other methods of tracking AJAX calls.With observables,it is very easy:

TypeScript Code:

import { pipe, range, timer, zip } from 'rxjs';
import { ajax } from 'rxjs/ajax';
import { retryWhen, map, mergeMap } from 'rxjs/operators';

function backoff(maxTries, ms) {
 return pipe(
   retryWhen(attempts => zip(range(1, maxTries), attempts)
     .pipe(
       map(([i]) => i * i),
       mergeMap(i =>  timer(i * ms))
     )
   )
 );
}

ajax('/api/endpoint')
  .pipe(backoff(3, 250))
  .subscribe(data => handleData(data));

function handleData(data) {
  // ...
}

Live Demo:

It is just a code snippet explaining a particular concept and may not have any output

See the Pen exponetial_backoff by w3resource (@w3resource) on CodePen.


Example communication between components

Message Service

With the message service you can subscribe to new messages in any component with getMessage() method, send messages from any component with the sendMessage(message: string) method, and clear messages from any component with the clearMessages() method.

The clearMessages() method actually just sends an empty message by calling this.subject.next() without any arguments, the logic to clear the messages when an empty message is received is in the app component below.

TypeScript Code:


import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs';

@Injectable({ providedIn: 'root' })
export class MessageService {
    private subject = new Subject();

    sendMessage(message: string) {
        this.subject.next({ text: message });
    }

    clearMessages() {
        this.subject.next();
    }

    getMessage(): Observable {
        return this.subject.asObservable();
    }
}

Live Demo:

It is just a code snippet explaining a particular concept and may not have any output

See the Pen message_component.ts by w3resource (@w3resource) on CodePen.


Home Component that Receives Messages

The app component uses the message service to subscribe to new messages and push them into the messages array which is displayed in the app component template. If an empty message is received then the messages array is cleared which automatically removes the messages from the UI.

TypeScript Code:

import { Component, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';

import { MessageService } from './_services/index';

@Component({
    selector: 'app',
    templateUrl: 'app.component.html'
})

export class AppComponent implements OnDestroy {
    messages: any[] = [];
    subscription: Subscription;

    constructor(private messageService: MessageService) {
        // subscribe to home component messages
        this.subscription = this.messageService.getMessage().subscribe(message => {
          if (message) {
            this.messages.push(message);
          } else {
            // clear messages when empty message received
            this.messages = [];
          }
        });
    }

    ngOnDestroy() {
        // unsubscribe to ensure no memory leaks
        this.subscription.unsubscribe();
    }
}

Live Demo:

It is just a code snippet explaining a particular concept and may not have any output

See the Pen receiveMessage.ts by w3resource (@w3resource) on CodePen.


Home Component that Sends Messages

The home component uses the message service to send messages to the app component.

TypeScript Code:

import { Component } from '@angular/core';

import { MessageService } from '../_services/index';

@Component({ templateUrl: 'home.component.html' })
export class HomeComponent {
    constructor(private messageService: MessageService) { }

    sendMessage(): void {
        // send message to subscribers via observable subject
        this.messageService.sendMessage('Message from Home Component to App Component!');
    }

    clearMessages(): void {
        // clear messages
        this.messageService.clearMessages();
    }
}

Live Demo:

It is just a code snippet explaining a particular concept and may not have any output

See the Pen sendMessage.ts by w3resource (@w3resource) on CodePen.


There are more examples of how angular observables can be applied to real word applications like the case of creating a Simple Infinite scroller directive or making request Httpclient and consuming the API like making request to YouTube API to create a video search or even for an effective login operation in angular, where the user gets an async notification for the results of the login attempt. Have fun get your hands even dirtier.

Previous: Comparing observables with other techniques
Next: Bootstrapping



Follow us on Facebook and Twitter for latest update.