ANGULAR
Complete Angular Tutorial For Beginners Introduction to Angular | What is Angular? Architecture Overview & Concepts of Angular How to Install Angular How to Create a new project in Angular Bootstrapping in Angular: How It Works Internally Angular Components Overview & Examples Data Binding in Angular Interpolation in Angular Property Binding in Angular Event Binding in Angular ngModel & Two way Data binding in Angular NgModelChange & Change Event in Angular Child/Nested Components in Angular angular directives angular ngFor directive ngSwitch, ngSwitchcase, ngSwitchDefa ult Angular Example How to use ngIf, else, then in Angular By example NgClass Example Conditionally apply class Angular ngStyle Directive Angular Trackby to improve ngFor Performance How to Create & Use Custom Directive In Angular Working with Angular Pipes How to Create Custom Pipe in Angular Formatting Dates with Angular Date Pipe Using Angular Async Pipe with ngIf & ngFor angular keyValue pipe Using Angular Pipes in Components or Services Angular Component Communication & Sharing Data Angular Pass data to child component Angular Pass data from Child to parent component Component Life Cycle Hooks in Angular Angular ngOnInit And ngOnDestroy Life Cycle hook Angular ngOnChanges life Cycle Hook Angular ngDoCheck Life Cycle Hook Angular Forms Tutorial: Fundamentals & Concep t s Angular Template-driven forms example How to set value in template-driven forms in Angular Angular Reactive Forms Example Using Angular FormBuilder to build Forms SetValue & PatchValue in Angular StatusChanges in Angular Forms ValueChanges in Angular Forms FormControl in Angular FormGroup in Angular Angular FormArray Example Nested FormArray Example Add Form Fields Dynamically SetValue & PatchValue in FormArray Angular Select Options Example in Angular Introduction to Angular Services Introduction to Angular Dependency Injection Angular Injector, @Injectable & @Inject Angular Providers: useClass, useValue, useFactory & useExisting Injection Token in Angular How Dependency Injection & Resolution Works in Angular Angular Singleton Service ProvidedIn root, any & platform in Angular @Self, @SkipSelf & @Optional Decorators Angular '@Host Decorator in Angular ViewProviders in Angular Angular Reactive Forms Validation Custom Validator in Angular Reactive Form Custom Validator with Parameters in Angular Inject Service Into Validator in Angular template_driven_form_validation_in_angular Custom Validator in Template Driven Forms in Angular Angular Async Validator Example Cross Field or Multi Field Validation Angular How to add Validators Dynamically using SetValidators in Angular Angular HttpClient Tutorial & Example Angular HTTP GET Example using httpclient Angular HTTP POST Example URL Parameters, Query Parameters, httpparams in Angular HttpClient Angular HTTPHeaders Example Understanding HTTP Interceptors in Angular Angular Routing Tutorial with Example Location Strategy in Angular Angular Route Params Angular : Child Routes / Nested Route Query Parameters in Angular Angular Pass Data to Route: Dynamic/Static RouterLink, Navigate & NavigateByUrl to Navigate Routes RouterLinkActive in Angular Angular Router Events ActivatedRoute in Angular Angular Guards Tutorial Angular CanActivate Guard Example Angular CanActivateChild Example Angular CanDeactivate Guard Angular Resolve Guard Introduction to Angular Modules or ngModule Angular Routing between modules Angular Folder Structure Best Practices Guide to Lazy loading in Angular Angular Preloading Strategy Angular CanLoad Guard Example Ng-Content & Content Projection in Angular Angular @input, @output & EventEmitter Template Reference Variable in Angular ng-container in Angular How to use ng-template & TemplateRef in Angular How to Use ngTemplateOutlet in Angular '@Hostbinding and @Hostlistener_in_Angular Understanding ViewChild, ViewChildren &erylist in Angular ElementRef in Angular Renderer2 Example: Manipulating DOM in Angular ContentChild and ContentChildren in Angular AfterViewInit, AfterViewChecked, AfterContentInit & AfterContentChecked in Angular Angular Decorators Observable in Angular using RxJs Create observable from a string, array & object in angular Create Observable from Event using FromEvent in Angular Using Angular observable pipe with example Angular Map Operator: Usage and Examples Filter Operator in Angular Observable Tap operator in Angular observable Using SwitchMap in Angular Using MergeMap in Angular Using concatMap in Angular Using ExhaustMap in Angular Take, TakeUntil, TakeWhile & TakeLast in Angular Observable First, Last & Single Operator in Angular Observable Skip, SkipUntil, SkipWhile & SkipLast Operators in Angular The Scan & Reduce operators in Angular DebounceTime & Debounce in Angular Delay & DelayWhen in Angular Using ThrowError in Angular Observable Using Catcherror Operator in Angular Observable ReTryWhen inReTry, ReTryWhen in Angular Observable Unsubscribing from an Observable in Angular Subjects in Angular ReplaySubject, BehaviorSubject & AsyncSubject in Angular Angular Observable Subject Example Sharing Data Between Components Angular Global CSS styles View Encapsulation in Angular Style binding in Angular Class Binding in Angular Angular Component Styles How to Install & Use Angular FontAwesome How to Add Bootstrap to Angular Angular Location Service: go/back/forward Angular How to use APP_INITIALIZER Angular Runtime Configuration Angular Environment Variables Error Handling in Angular Applications Angular HTTP Error Handling Angular CLI tutorial ng new in Angular CLI How to update Angular to latest version Migrate to Standalone Components in Angular Create Multiple Angular Apps in One Project Set Page Title Using Title Service Angular Example Dynamic Page Title based on Route in Angular Meta service in Angular. Add/Update Meta Tags Example Dynamic Meta Tags in Angular Angular Canonical URL Lazy Load Images in Angular Server Side Rendering Using Angular Universal The requested URL was not found on this server error in Angular Angular Examples & Sample Projects Best Resources to Learn Angular Best Angular Books in 2020

Observable in Angular using RxJs

The Angular Observable tutorial (or Angular RxJs Tutorial ) covers what an observable is and how to use Observables in Angular applications. When we talk about Angular Observable, we hear a lot of terms like Reactive programming, data streams, observables, Observers, RxJS, etc. It is essential to understand these terms before we start using the observables.

Rx stands for Reactive programming. It is defined as programming with asynchronous data streams. So, it is essential that you understand what a data stream is.

What is a data stream?

A data stream is the data that arrives over some time. The stream of data can be anything. Like variables, user inputs, properties, caches, data structures, and even failures, etc

Consider the example of a sequence of x and y positions of mouse click events. Assume that the user has clicked on the locations (12, 15), (10, 12), (15, 20), and (17, 15) in that order.

The following diagram shows how the values arrive over a period of time. As you can see, the stream emits the values as they happen, i.e., asynchronously.

image

mouse click events as data streams

Value is not the only thing that streams emit. The stream may complete as the user closes the window or app. Or an error may happen, resulting in the stream’s closure. At any point in time, the stream may emit the following three things.

Value: i.e., the next value in the stream
Complete: The stream has ended
Error: The error has stopped the stream.

The following diagram shows all three possibilities in a stream

image

mouse click events as data streams with emit error and complete events

As said earlier the stream of data can be anything. For Example

  1. Mouse click or Mouse hover events with x & y positions
  2. Keyboard events like keyup, keydown, keypress, etc
  3. Form events like value changes etc
  4. Data that arrives after an HTTP request
  5. User Notifications
  6. Measurements from any sensor

Important Points regarding streams can

  1. Emit zero, one or more values of any time.
  2. It can also emit errors.
  3. Must emit the complete signal when completed (finite streams).
  4. Can be infinite, and they never complete

Now we have understood what a data stream is, let us look at what is Reactive Programming is

Reactive Programming

Reactive programming is about creating the stream, emitting value, error, or complete signals, manipulating, transferring, or doing something useful with the data streams.

This is where the RxJs come into the picture.

The introduction to Reactive Programming you’ve been missing gives you a very nice introduction to Reactive Programming. Also, refer to Introduction to Rx

What is RxJS

The RxJS (Reactive Extensions Library for JavaScript) is a Javascript library that allows us to work with asynchronous data streams.

Observable in Angular

Angular uses the RxJS library heavily in its framework to implement Reactive Programming. Some of the examples where reactive programming is used are

  1. Reacting to an HTTP request in Angular
  2. Value changes / Status Changes in Angular Forms
  3. The Router and Forms modules use observables to listen for and respond to user-input events.
  4. You can define custom events that send observable output data from a child to a parent component.
  5. The HTTP module uses observables to handle AJAX requests and responses.

The RxJs has two main players

  1. Observable
  2. Observers ( Subscribers)

What is an Observable in Angular

Observable is a function that converts the ordinary data stream into an observable one. You can think of Observable as a wrapper around the ordinary data stream.

An observable stream or simple Observable emits the value from the stream asynchronously. It emits the complete signals when the stream completes or an error signal if the stream errors out.

Observables are declarative. You define an observable function just like any other variable. The observable starts to emit values only when someone subscribes to it.

Who are the observers (subscribers)

The Observable is only useful if someone consumes the value emitted by the observable. We call them observers or subscribers.

The observers communicate with the Observable using callbacks

The observer must subscribe to the observable to receive the value from the observable. While subscribing, it optionally passes the three callbacks. next(), error() & complete()

image
Angular Observable Tutorial on how observable and observers communicates with callbacks

The observable emits the value as soon as the observer or consumer subscribes to it.

The observable invokes the next() callback whenever the value arrives in the stream. It passes the value as the argument to the next callback. If the error occurs, then the error() callback is invoked. It invokes the complete() callback when the stream completes.

  1. Observers/subscribers subscribe to Observables.
  2. The observer registers three callbacks with the observable at the time of subscribing. i .e next(), error() & complete()
  3. All three callbacks are optional
  4. The observer receives the data from the observer via the next() callback
  5. They also receive the errors and completion events from the Observable via the error() & complete() callbacks

Angular Observable tutorial

Now we have learned the basics of the RxJs Observable, let us now see how it works using an example.

Create a new project in angular. Remove the contents from app.component.html. Open the app.component.ts

Import the required libraries

RxJs library is installed automatically when you create the Angular project. Hence there is no need to install it.

Import the Observable from the rxjs library

                              

import { Observable } from 'rxjs';
                            
                        

Observable Creation

There are a few ways in which you can create observable in angular. The simplest is to use the Observable constructor. The observable constructor takes the observer (or subscriber) as its argument. The subscriber will run when this observable’s subscribe() method executes.

The following example creates an observable of a stream of numbers 1, 2, 3, 4, 5

                              
 
obs = new Observable((observer) => {
     console.log("Observable starts")
     observer.next("1")
     observer.next("2")
     observer.next("3")
     observer.next("4")
     observer.next("5")
   })
                            
                        

The variable obs is now of Type observable.

The above example declares the obs as observable but does not instantiate it. To make the observable emit values, we need to subscribe to them.

image
Creating observable in the Angular Observable Tutorial app

In the above example, we used the Observable Constructor to create the Observable. Many operators are available with the RxJS library, which makes creating the observable easy. These operators help us to create observables from an array, string, promise, any iterable, etc. Here is list of some of the commonly used operators

  • create
  • defer
  • empty
  • from
  • fromEvent
  • interval
  • of
  • range
  • throwError
  • timer
  • Subscribing to the observable

    We subscribe to the observable by invoking the subscribe method on it.

    We either pass an observer object or the next() callback as an argument. The arguments are optional. (The subscribe method signature was changed in RxJs 6.4. Scroll down for older syntax.)

    An observer object is an object that optionally contains the next, error and complete methods. The signature of the observer object is shown below.

                                  
    export interface Observer<T> {  
      next: (value: T) => void;  
      error: (err: any) => void;  
      complete: () => void;  
    }
     
                                
                            

    The code below shows subscribing to an observable using the observer object. The next method is invoked whenever the observable emits data. It invokes the error method when an error occurs and the complete method when the observable completes.

                                  
    
      ngOnInit() {
        this.obs.subscribe( 
          {
            next: (val) => {
              console.log(val);
            }, //next callback
            error: (error) => {
              console.log('error');
            }, //error callback
            complete:() => {
              console.log('Completed');
             } //complete callback
          }
        );
      }
                                
                            

    The complete app.component.ts code is shown below.

                                  
     
    import { Component, OnInit } from '@angular/core';
    import { Observable } from 'rxjs';
     
    @Component({
      selector: 'my-app',
      template: `
      
      <h1>Angular Observable Tutorial</h1>
     
    <br><br><br>
    Refer
    <a href="https://www.tektutorialshub.com/angular/angular-observable-tutorial-using-rxjs/">Angular Observable
      Tutorial</a>
      `
    })
    export class AppComponent implements OnInit {
      
     
      obs = new Observable(observer => {
        console.log('Observable starts');
        observer.next('1');
        observer.next('2');
        observer.next('3');
        observer.next('4');
        observer.next('5');
      });
     
      ngOnInit() {
        this.obs.subscribe( {
          next: (val) => {
            console.log(val);
          }, //next callback
          error: (error) => {
            console.log('error');
          }, //error callback
          complete:() => {
            console.log('Completed');
          } //complete callback
        }
        );
      }
    }
     
                                
                            

    Now, run the code and watch the output in debug window.

    Adding interval

    We can add a timeout to insert a delay in each next() callback

                                  
    
      obs = new Observable((observer) => {
        console.log("Observable starts")
     
        setTimeout(() => { observer.next("1") }, 1000);
        setTimeout(() => { observer.next("2") }, 2000);
        setTimeout(() => { observer.next("3") }, 3000);
        setTimeout(() => { observer.next("4") }, 4000);
        setTimeout(() => { observer.next("5") }, 5000);
        
      })
     
                                
                            
    image
    Angular Observable tutorial example app

    Error event

    As mentioned earlier, the observable can also emit an error. This is done by invoking the error() callback and passing the error object. The observables stop after emitting the error signal. Hence in the following example, values 4 & 5 are never emitted.

                                  
     
     obs = new Observable((observer) => {
        console.log("Observable starts")
     
        setTimeout(() => { observer.next("1") }, 1000);
        setTimeout(() => { observer.next("2") }, 2000);
        setTimeout(() => { observer.next("3") }, 3000);
        setTimeout(() => { observer.error("error emitted") }, 3500);    //sending error event. observable stops here
        setTimeout(() => { observer.next("4") }, 4000);          //this code is never called
        setTimeout(() => { observer.next("5") }, 5000);
        
      })
                                
                            

    You can send the error object as the argument to the error method

    image
    Observable with the error event

    Complete Event

    Similarly, the complete event. The observables stop after emitting the complete signal. Hence in the following example, values 4 & 5 are never emitted.

                                  
     
        obs = new Observable((observer) => {
        console.log("Observable starts")
     
        setTimeout(() => { observer.next("1") }, 1000);
        setTimeout(() => { observer.next("2") }, 2000);
        setTimeout(() => { observer.next("3") }, 3000);
        setTimeout(() => { observer.complete() }, 3500);   //sending complete event. observable stops here
        setTimeout(() => { observer.next("4") }, 4000);    //this code is never called
        setTimeout(() => { observer.next("5") }, 5000);
        
      })
     
                                
                            
    image
    Observable with complete event

    Observable Operators

    The Operators are functions that operate on an Observable and return a new Observable.

    The power of observable comes from the operators. You can use them to manipulate the incoming observable, filter it, merge it with another observable, alter the values or subscribe to another observable.

    You can also chain each operator one after the other using the pipe. Each operator in the chain gets the observable from the previous operator. It modifies it and creates a new observable, which becomes the input for the next observable.

    The following example shows the filer & map operators chained inside a pipe.The filter operator removes all data which is less than or equal to 2 and the map operator multiplies the value by 2.

    The input stream is [1,2,3,4,5] , while the output is [6, 8, 10].

                                  
    
    obs.pipe(
     obs = new Observable((observer) => {
        observer.next(1)
        observer.next(2)
        observer.next(3)
        observer.next(4)
        observer.next(5)
        observer.complete()
      }).pipe(
        filter(data => data > 2),   //filter Operator
        map((val) => {return val as number * 2}), //map operator
      )
     
                                
                            

    The following table lists some of the commonly used operators

    AREA OPERATORS
    Combination combineLatest, concat, merge, startWith , withLatestFrom, zip
    Filtering debounceTime, distinctUntilChanged, filter, take, takeUntil ,takeWhile, takeLast, first, last, single, skip, skipUntil, skipWhile, skipLast,
    Transformation bufferTime,concatMap, map, mergeMap , scan, switchMap, ExhaustMap, reduce
    Utility tap, delay, delaywhen
    Error Handling throwerror, catcherror, retry, retrywhen
    Multicasting share

    Unsubscribing from an Observable

    We must unsubscribe to close the observable when we no longer require it. If not, it may lead to memory leak & Performance degradation.

    To Unsubscribe from an observable, we need to call the Unsubscribe() method on the subscription. It will clean up all listeners and frees up the memory.

    To do that, first, create a variable to store the subscription

                                  
    
    obs: Subscription;
     
                                
                            

    Assign the subscription to the obs variable

                                  
    
    this.obs = this.src.subscribe(value => {
      console.log("Received " + this.id);
    });
     
     
                                
                            

    Call the unsubscribe() method in the ngOnDestroy method.

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

    When we destroy the component, the observable is unsubscribed and cleaned up.

    But you do not have to unsubscribe from every subscription. For Example, the observables, which emit the complete signal, close the observable.

    To learn more about it, refer to the tutorial Unsubscribing from an Observable in Angular.

    Summary

    Reactive programming is about programming the stream. The RxJS library brings Reactive Programming into Angular. Using RxJs, we can create an observable, emitting the next value, error, and complete signals to the subscriber of the observable.

    In the next few tutorials, we will learn more about the RxJs Observable