Angular throwError
February 18, 2019
RxJS throwError
operator is used to create an Observable
that emits an error notification immediately and no element. throwError
can be used composing with other Observable
, such as in a mergeMap
, switchMap
etc. throwError
is introduced in RxJS 6 and we need to use it in place of Observable.throw()
. Angular 6 has integrated RxJS 6 and Angular 6 onwards we can use throwError
that will return Observable
instance with error message. We catch error using catchError
returned by throwError
.
throwError
is imported as following.
import { throwError } from 'rxjs';
throwError
with examples step by step.
Contents
Technologies Used
Find the technologies being used in our example.1. Angular 7.0.0
2. Angular CLI 7.0.3
3. TypeScript 3.1.1
4. Node.js 10.3.0
5. NPM 6.1.0
6. RxJS 6.3.3
7. In-Memory Web API 0.6.1
Using throwError
Let us understand how to usethrowError
operator.
Example-1:
In this example, the
Observable
instance will emit 1,2,3,4 but for the number 3, we will throw error.
of(1,2,3,4).pipe( mergeMap(data => { if (data === 3) { return throwError('Error Occurred for data: '+ 3); } return of(data); }) ).subscribe(res => console.log(res), err => console.error(err) );
1 2 Error Occurred for data: 3
Here we will emit numbers after every 2 seconds and for number 2, an error is thrown.
interval(2000).pipe( mergeMap(x => x === 2 ? throwError('Error: Received 2') : of('a', 'b') ), ).subscribe(x => console.log(x), e => console.error(e) );
a b a b Error: Received 2
throwError, retry and catchError
Here we will create an example withthrowError
, retry
and catchError
.
of("A", "B").pipe( switchMap(el => { if (el === "B") { return throwError("Error occurred."); } return el; }), retry(2), catchError(err => { console.error(err); return throwError("User defined error."); }) ).subscribe(el => console.log(el), err => console.error(err), () => console.log("Processing Complete.") );
A A A Error occurred. User defined error.
Observable
emits element B, error is thrown by throwError
. The operator retry
resubscribes 2 times and finally error is caught by catchError
operator and then we again throw user defined error using throwError
. Process complete block will not execute because error occurs.
JavaScript throw vs RxJS throwError
JavaScriptthrow
statement throws user-defined exception. throw
does not return Observable
instance. Find the sample code snippet for throw
.
switchMap(el => { if (el === "B") { throw new Error("Error occurred."); } return el; })
throwError()
returns Observable
instance that emits only error and no element. Find the sample code for throwError()
.
switchMap(el => { if (el === "B") { return throwError("Error occurred."); } return el; })
Complete Example
book.component.tsimport { Component, OnInit } from '@angular/core'; import { of, throwError, interval } from 'rxjs'; import { switchMap, debounceTime, catchError, retry, mergeMap } from 'rxjs/operators'; import { BookService } from './book.service'; import { Book } from './book'; import { FormControl, FormBuilder, FormGroup } from '@angular/forms'; @Component({ selector: 'app-book', template: ` <h3>Search Book</h3> <form [formGroup]="bookForm"> ID: <input formControlName="bookId"> </form> <br/> <div *ngIf="book"> Id: {{book.id}}, Name: {{book.name}}, Category: {{book.category}} </div> ` }) export class BookComponent implements OnInit { book: Book; constructor(private bookService: BookService, private formBuilder: FormBuilder) { } ngOnInit() { of(1,2,3,4).pipe( mergeMap(data => { if (data === 3) { return throwError('Error Occurred for data: '+ 3); } return of(data); }) ).subscribe(res => console.log(res), err => console.error(err) ); interval(2000).pipe( mergeMap(x => x === 2 ? throwError('Error: Received 2') : of('a', 'b') ), ).subscribe(x => console.log(x), e => console.error(e) ); //------------------------- this.retryAndHandleError(); this.searchBook(); } retryAndHandleError() { of("A", "B").pipe( switchMap(el => { if (el === "B") { return throwError("Error occurred."); } return el; }), retry(2), catchError(err => { console.error(err); return throwError("User defined error."); }) ).subscribe(el => console.log(el), err => console.error(err), () => console.log("Processing Complete.") ); } bookId = new FormControl(); bookForm: FormGroup = this.formBuilder.group({ bookId: this.bookId } ); searchBook() { this.bookId.valueChanges.pipe( debounceTime(1000), switchMap(id => { return this.bookService.getBook(id); }), catchError(err => { return throwError('User defined error.'); }) ).subscribe(res => this.book = res, err => { console.error(err); this.book = null; this.searchBook(); } ) } }
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; import { Book } from './book'; @Injectable({ providedIn: 'root' }) export class BookService { bookUrl = "/api/books"; constructor(private http: HttpClient) { } getBook(id: number): Observable<Book> { let url = this.bookUrl + "/" + id; return this.http.get<Book>(url); } }
export interface Book { id: number; name: string; category: string; }
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <app-book></app-book> ` }) export class AppComponent { }
import { InMemoryDbService } from 'angular-in-memory-web-api'; export class TestData implements InMemoryDbService { createDb() { let bookDetails = [ { id: 101, name: 'Angular by Krishna', category: 'Angular' }, { id: 102, name: 'Core Java by Vishnu', category: 'Java' }, { id: 103, name: 'NgRx by Rama', category: 'Angular' } ]; return { books: bookDetails }; } }
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { HttpClientModule } from '@angular/common/http'; import { AppComponent } from './app.component'; import { BookComponent } from './book.component'; //For InMemory testing import { InMemoryWebApiModule } from 'angular-in-memory-web-api'; import { TestData } from './test-data'; @NgModule({ imports: [ BrowserModule, HttpClientModule, FormsModule, ReactiveFormsModule, InMemoryWebApiModule.forRoot(TestData) ], declarations: [ AppComponent, BookComponent ], providers: [ ], bootstrap: [ AppComponent ] }) export class AppModule { }
Run Application
To run the application, find the steps.1. Download source code using download link given below on this page.
2. Use downloaded src in your Angular CLI application. To install Angular CLI, find the link.
3. Install angular-in-memory-web-api@0.6.1
4. Run ng serve using command prompt.
5. Access the URL http://localhost:4200
We can see output in console as following.

References
RxJS throwErrorAngular RxJS retry
Angular catchError