0% found this document useful (0 votes)
31 views185 pages

What Are Components in Angular

Uploaded by

clouditlab9
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
31 views185 pages

What Are Components in Angular

Uploaded by

clouditlab9
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 185

What are components in Angular?

Components are the basic building blocks of Angular applications.


In a simpler manner, we can say components are UI/ View elements along with the mechanism to show and operate
on data.
The Angular Team defines a component as the Patch of the screen that we call a View which declares the reusable
building blocks for an application.
So, A component is anything which is visible on the screen, which can be reused again and again.
#Prerequisites
Node installed on your machine
NPM installed on your machine
Basic Knowledge of JavaScript
Installing Angular CLI 8 : npm install -g @angular/cli
Creating your Angular 8 Project : ng new angular-example
Creating Components : ng g c payment-components
Run on local Server on http://localhost:4200 : ng serve
3 ways to communicate data between Angular components
Parent to Child: Sharing Data via Input
Child to Parent: Sharing Data via ViewChild with AfterViewInit
Child to Parent: Sharing Data via Output() and EventEmitter
1. Parent to Child: Sharing Data via Input
To share data from parent to child component via @Input Decorator.
@Input links a property of a child component with a value that was given by the parent component.
For e.g :
Create 2 components parent.component.ts and child.component.ts
Let's create a simple string variable in our parent.component.ts file, It will contain the message that we want to give
to our child.
Add bellow code in parent.component.ts file :
import { Component } from '@angular/core';

@Component({
selector: 'app-parent',
template: `
<app-child [childMessage]="parentMessage"></app-child>
`,
styleUrls: ['./parent.component.css']
})

export class ParentComponent{

parentMessage = "message from parent";

constructor() { }
}
parent.component.ts
Add bellow code in child.component.ts file :
import { Component, Input } from '@angular/core';

@Component({
selector: 'app-child',
template: ` Say {{ message } `,
styleUrls: ['./child.component.css']
})

export class ChildComponent {

@Input() childMessage: string;


constructor() { }
}

child.component.ts
2. Child to Parent: Sharing Data via ViewChild with AfterViewInit
ViewChild allows a child component to be injected into a parent component.
It will give the parent access to its attributes and functions.
A Child won’t be available to give access until the view has been initialized.
This means we need to implement the AfterViewInit lifecycle hook to receive the data from the child.
Add bellow code in parent.component.ts file :
import { Component, ViewChild, AfterViewInit } from '@angular/core';
import { ChildComponent } from "../child/child.component";

@Component({
selector: 'app-parent',
template: `
Message: {{ message }}
<app-child></app-child>
`,
styleUrls: ['./parent.component.css']
})

export class ParentComponent implements AfterViewInit {

@ViewChild(ChildComponent) child;

constructor() { }

Message:string;

ngAfterViewInit() {
this.message = this.child.message
}
}
parent.component.ts
Add bellow code in child.component.ts
import { Component} from '@angular/core';

@Component({
selector: 'app-child',
template: ` `,
styleUrls: ['./child.component.css']
})

export class ChildComponent {

message = 'Hello Angular!';

constructor() { }

}
child.component.ts
3. Child to Parent: Sharing Data via Output() and EventEmitter
Another way to share data is to emit data from the child component which can be listed by the parent component.
This approach is ideal when you want to share data changes that occur on things like button clicks, form entries, and
other user events.
For e.g.
In the parent, we create a function to receive the message and set it equal to the message variable.
In the child, we declare a messageEvent variable with the Output decorator and set it equal to a new event emitter.
Then we create a function named sendMessage that calls emit on this event with the message we want to send.
Lastly, we create a button to trigger this function.
The parent can now subscribe to this messageEvent that’s outputted by the child component, then run the receive
message function whenever this event occurs.
Add bellow code in parent.component.ts file :
import { Component } from '@angular/core';

@Component({
selector: 'app-parent',
template: `
Message: {{message}}
<app-child (messageEvent)="receiveMessage($event)"></app-child>
`,
styleUrls: ['./parent.component.css']
})

export class ParentComponent {

constructor() { }

Message:string;

receiveMessage($event) {
this.message = $event
}
}

parent.component.ts
Add bellow code in child.component.ts file :
import { Component, Output, EventEmitter } from '@angular/core';

@Component({
selector: 'app-child',
template: `
<button (click)="sendMessage()">Send Message</button>
`,
styleUrls: ['./child.component.css']
})

export class ChildComponent {

message: string = "Hey Angular!"

@Output() messageEvent = new EventEmitter<string>();

constructor() { }

sendMessage() {
this.messageEvent.emit(this.message)
}
}
child.component.ts
#Conclusion
Here we define how to share data between component in Angular 8
We can share data from parent to child via @Input
We can share data from child to parent via ViewChild
We can share data from child to parent via @Output for button clicks or Form entries
What are Subjects ?
A Subject is a special type of Observable that allows values to be multicasted to many Observers. The subjects are
also observers because they can subscribe to another observable and get value from it, which it will multicast to all
of its subscribers.
Basically, a subject can act as both observable & an observer.
How does Subjects work
Subjects implement both subscribe method and next, error & complete methods. It also maintains a collection
of observers[]

An Observer can subscribe to the Subject and receive value from it. Subject adds them to its collection observers.
Whenever there is a value in the stream it notifies all of its Observers.
The Subject also implements the next, error & complete methods. Hence it can subscribe to another observable and
receive values from it.
Creating a Subject in Angular
The following code shows how to create a subject in Angular.
app.component.ts
1
2 import { Component, VERSION } from "@angular/core";
3 import { Subject } from "rxjs";
4
5 @Component({
6 selector: "my-app",
7 templateUrl: "./app.component.html",
8 styleUrls: ["./app.component.css"]
9 })
10 export class AppComponent {
11
12 subject$ = new Subject();
13
14 ngOnInit() {
15
16 this.subject$.subscribe(val => {
17 console.log(val);
18 });
19
20 this.subject$.next("1");
21 this.subject$.next("2");
22 this.subject$.complete();
23 }
24 }
25
Stackblitz
The code that creates a subject.
1
2 subject$ = new Subject();
3
We subscribe to it just like any other observable.
1
2 this.subject$.subscribe(val => {
3 console.log(val);
4 });
5
The subjects can emit values. You can use the next method to emit the value to its subscribers. Call
the complete & error method to raise complete & error notifications.
1
2 this.subject$.next("1");
3 this.subject$.next("2");
4 this.subject$.complete();
5 //this.subject$.error("error")
6
That’s it.
Subject is an Observable
The subject is observable. It must have the ability to emit a stream of values
The previous example shows, we can use the next method to emit values into the stream.
1
2 this.subject$.next("1");
3 this.subject$.next("2");
4
Subject is hot Observable
Observables are classified into two groups. Cold & Hot
Cold observable
The cold observable does not activate the producer until there is a subscriber. This is usually the case when the
observable itself produces the data.
1
2 import { Component, VERSION } from "@angular/core";
3 import { Subject, of } from "rxjs";
4
5 import { Component, VERSION } from "@angular/core";
6 import { Observable, of } from "rxjs";
7
8 @Component({
9 selector: "my-app",
10 templateUrl: "./app.component.html",
11 styleUrls: ["./app.component.css"]
12 })
13 export class AppComponent {
14 obs1$ = of(1, 2, 3, 4);
15
16 obs$ = new Observable(observer => {
17 console.log("Observable starts");
18 observer.next("1");
19 observer.next("2");
20 observer.next("3");
21 observer.next("4");
22 observer.next("5");
23 });
24
25 ngOnInit() {
26 this.obs$.subscribe(val => {
27 console.log(val);
28 });
29 }
30 }
31
32
Stackblitz
The Producer is one that produces the data. In the above example above it is part of the observable itself. We cannot
use that to emit data ourselves.

Even in the following code, the producer is part of the observable.


1
2 obs1$ = of(1, 2, 3, 4);
3
The producer produces the value only when a subscriber subscribes to it.
Hot observable
The hot observable does not wait for a subscriber to emit the data. It can start emitting the values right away. The
happens when the producer is outside the observable.
Consider the following example. We have created an observable using subject. In the ngOnInit, we emit the values &
close the Subject. That is without any subscribers.
Since there were no subscribers, no one receives the data. But that did not stop our subject from emitting data.
1
2 import { Component, VERSION } from "@angular/core";
3 import { Subject } from "rxjs";
4
5 @Component({
6 selector: "my-app",
7 templateUrl: "./app.component.html",
8 styleUrls: ["./app.component.css"]
9 })
10 export class AppComponent {
11
12 subject$ = new Subject();
13
14 ngOnInit() {
15 this.subject$.next("1");
16 this.subject$.next("2");
17 this.subject$.complete();
18 }
19 }
20
21
Stackblitz
Now, consider the following example. Here the subjects the values 1 & 2 are lost because the subscription happens
after they emit values.
1
2 import { Component, VERSION } from "@angular/core";
3 import { Subject } from "rxjs";
4
5 @Component({
6 selector: "my-app",
7 templateUrl: "./app.component.html",
8 styleUrls: ["./app.component.css"]
9 })
10 export class AppComponent {
11 subject$ = new Subject();
12
13 ngOnInit() {
14 this.subject$.next("1");
15 this.subject$.next("2");
16
17 this.subject$.subscribe(val => {
18 console.log(val);
19 });
20
21 this.subject$.next("3");
22 this.subject$.complete();
23 }
24 }
25
Stackblitz
Every Subject is an Observer
The observer needs to implement the next, error & Complete callbacks (all optional) to become an Observer
1
2 import { Component, VERSION } from "@angular/core";
3 import { Observable, Subject } from "rxjs";
4
5 @Component({
6 selector: "my-app",
7 templateUrl: "./app.component.html",
8 styleUrls: ["./app.component.css"]
9 })
10 export class AppComponent {
11 subject$ = new Subject();
12
13 observable = new Observable(observer => {
14 observer.next("first");
15 observer.next("second");
16 observer.error("error");
17 });
18
19 ngOnInit() {
20 this.subject$.subscribe(val => {
21 console.log(val);
22 });
23
24 this.observable.subscribe(this.subject$);
25 }
26 }
27
Stackblitz
The following example creates a Subject & and an Observable
We subscribe to the Subject in the ngOnInit method.
We also subscribe to the observable, passing the subject. Since the subject implements the next method, it receives
the values from the observable and emits them to the subscribers.
The Subject here acts as a proxy between the observable & subscriber.
1
2 this.observable.subscribe(this.subject$);
3
Subjects are Multicast
Another important distinction between observable & subject is that subjects are multicast.
More than one subscriber can subscribe to a subject. They will share the same instance of the observable. This
means that all of them receive the same event when the subject emits it.
Multiple observers of an observable, on the other hand, will receive a separate instance of the observable.
Multicast vs Unicast
The Subjects are multicast.
Consider the following example, where we have an observable and subject defined. The observable generates a
random number and emits it.
1
2 import { Component, VERSION } from "@angular/core";
3 import { from, Observable, of, Subject } from "rxjs";
4
5 @Component({
6 selector: "my-app",
7 templateUrl: "./app.component.html",
8 styleUrls: ["./app.component.css"]
9 })
10 export class AppComponent {
11 observable$ = new Observable<number>(subscriber => {
12 subscriber.next(Math.floor(Math.random() * 200) + 1);
13 });
14
15 subject$ = new Subject();
16
17 ngOnInit() {
18 this.observable$.subscribe(val => {
19 console.log("Obs1 :" + val);
20 });
21
22 this.observable$.subscribe(val => {
23 console.log("Obs2 :" + val);
24 });
25
26 this.subject$.subscribe(val => {
27 console.log("Sub1 " + val);
28 });
29 this.subject$.subscribe(val => {
30 console.log("Sub2 " + val);
31 });
32
33 this.subject$.next(Math.floor(Math.random() * 200) + 1);
34 }
35 }
36
Stackblitz
We have two subscribers of the observable. Both these subscribers will get different values. This is because
observable on subscription creates a separate instance of the producer. Hence each one will get a different random
number
1
2 this.observable$.subscribe(val => {
3 console.log("Obs1 :" + val);
4 });
5
6 this.observable$.subscribe(val => {
7 console.log("Obs2 :" + val);
8 });
9
Next, we create two subscribers to the subject. The subject emits the value using the random number. Here both
subscribets gets the same value.
1
2 this.subject$.subscribe(val => {
3 console.log("Sub1 " + val);
4 });
5 this.subject$.subscribe(val => {
6 console.log("Sub2 " + val);
7 });
8
9 this.subject$.next(Math.floor(Math.random() * 200) + 1);
10
Subjects maintain a list of subscribers
Whenever a subscriber subscribes to a subject, it will add it to an array of subscribers. This way Subject keeps track
of its subscribers and emits the event to all of them.
There are other types of subjects
What we have explained to you is a simple subject. But there are few other types of subjects. They are
ReplaySubject
BehaviorSubject
AsyncSubject
We will talk about them in the next tutorial.
ReplaySubject, BehaviorSubject & AsyncSubject in Angular
2 Comments / 4 minutes of reading / May 1, 2021
Subjects in Angular
Angular Subject Example

ReplaySubject, BehaviorSubject & AsyncSubject are special types of subjects in Angular. In this tutorial let us learn
what are they, how they work & how to use them in Angular

00:02/03:27
Table of Contents
BehaviorSubject
ReplaySubject
AsyncSubject
Reference
BehaviorSubject
BehaviorSubject requires an initial value and stores the current value and emits it to the new subscribers.
1
2 import { Component, VERSION } from "@angular/core";
3 import { BehaviorSubject, Subject } from "rxjs";
4
5 @Component({
6 selector: "my-app",
7 templateUrl: "./app.component.html",
8 styleUrls: ["./app.component.css"]
9 })
10 export class AppComponent {
11 subject$ = new BehaviorSubject("0");
12
13 ngOnInit() {
14 this.subject$.subscribe(val => {
15 console.log("Sub1 " + val);
16 });
17
18 this.subject$.next("1");
19 this.subject$.next("2");
20
21 this.subject$.subscribe(val => {
22 console.log("sub2 " + val);
23 });
24
25 this.subject$.next("3");
26 this.subject$.complete();
27 }
28 }
29
30
31
32 ***Result***
33
34 Sub1 0
35 Sub1 1
36 Sub1 2
37 sub2 2
38 Sub1 3
39 sub2 3
40
41
StackBlitz
We create a new BehaviorSubject providing it an initial value or seed value. The BehaviorSubject stores the initial
value.
1
2 subject$ = new BehaviorSubject("0");
3
As soon as the first subscriber subscribes to it, the BehaviorSubject emits the stored value. i.e. 0
1
2 this.subject$.subscribe(val => {
3 console.log("Sub1 " + val);
4 });
5
We emit two more values. The BehaviorSubject stores the last value emitted i.e. 2
1
2 this.subject$.next("1");
3 this.subject$.next("2");
4
Now, Subscriber2 subscribes to it. It immediately receives the last value stored i.e. 2
1
2 this.subject$.subscribe(val => {
3 console.log("sub2 " + val);
4 });
5
ReplaySubject
ReplaySubject replays old values to new subscribers when they first subscribe.
The ReplaySubject will store every value it emits in a buffer. It will emit them to the new subscribers in the order it
received them. You can configure the buffer using the arguments bufferSize and windowTime
bufferSize: No of items that ReplaySubject will keep in its buffer. It defaults to infinity.
windowTime: The amount of time to keep the value in the buffer. Defaults to infinity.
Example
1
2
3 import { Component, VERSION } from "@angular/core";
4 import { ReplaySubject, Subject } from "rxjs";
5
6 @Component({
7 selector: "my-app",
8 templateUrl: "./app.component.html",
9 styleUrls: ["./app.component.css"]
10 })
11 export class AppComponent {
12 subject$ = new ReplaySubject();
13
14 ngOnInit() {
15 this.subject$.next("1");
16 this.subject$.next("2");
17
18 this.subject$.subscribe(
19 val => console.log("Sub1 " + val),
20 err => console.error("Sub1 " + err),
21 () => console.log("Sub1 Complete")
22 );
23
24 this.subject$.next("3");
25 this.subject$.next("4");
26
27 this.subject$.subscribe(val => {
28 console.log("sub2 " + val);
29 });
30
31 this.subject$.next("5");
32 this.subject$.complete();
33
34 this.subject$.error("err");
35 this.subject$.next("6");
36
37 this.subject$.subscribe(
38 val => {
39 console.log("sub3 " + val);
40 },
41 err => console.error("sub3 " + err),
42 () => console.log("Complete")
43 );
44 }
45 }
46
47 ***Result***
48 Sub1 1
49 Sub1 2
50 Sub1 3
51 Sub1 4
52 sub2 1
53 sub2 2
54 sub2 3
55 sub2 4
56 Sub1 5
57 sub2 5
58 Sub1 Complete
59 sub3 1
60 sub3 2
61 sub3 3
62 sub3 4
63 sub3 5
64 sub3 err
65
Stackblitz
First, we create a ReplaySubject
1
2 subject$ = new ReplaySubject();
3
ReplaySubject emits two values. It will also store these in a buffer.
1
2 this.subject$.next("1");
3 this.subject$.next("2");
4
We subscribe to it. The observer will receive 1 & 2 from the buffer
1
2 this.subject$.subscribe(
3 val => console.log("Sub1 " + val),
4 err => console.error("Sub1 " + err),
5 () => console.log("Sub1 Complete")
6 );
7
We subscribe again after emitting two more values. The new subscriber will also receive all the previous values.
1
2 this.subject$.next("3");
3 this.subject$.next("4");
4
5 this.subject$.subscribe(val => {
6 console.log("sub2 " + val);
7 });
8
We emit one more value & complete. All the subscribers will receive complete. They will not receive any further
values or notifcations.
1
2 this.subject$.next("5");
3 this.subject$.complete();
4
5
We now fire an error notification and a value. None of the previous subscribers will receive this as they are already
closed.
1
2 this.subject$.error("err");
3 this.subject$.next("6");
4
Now, we subscribe again. The subscriber will receive all the values up to Complete. But will not receive
the Complete notification, instead, it will receive the Error notification.
1
2 this.subject$.subscribe(
3 val => {
4 console.log("sub3 " + val);
5 },
6 err => console.error("sub3 " + err),
7 () => console.log("Complete")
8 );
9
AsyncSubject
AsyncSubject only emits the latest value only when it completes. If it errors out then it will emit an error, but will not
emit any values.
1
2 import { Component, VERSION } from "@angular/core";
3 import { AsyncSubject, Subject } from "rxjs";
4
5 @Component({
6 selector: "my-app",
7 templateUrl: "./app.component.html",
8 styleUrls: ["./app.component.css"]
9 })
10 export class AppComponent {
11 subject$ = new AsyncSubject();
12
13 ngOnInit() {
14 this.subject$.next("1");
15 this.subject$.next("2");
16
17 this.subject$.subscribe(
18 val => console.log("Sub1 " + val),
19 err => console.error("Sub1 " + err),
20 () => console.log("Sub1 Complete")
21 );
22
23 this.subject$.next("3");
24 this.subject$.next("4");
25
26 this.subject$.subscribe(val => {
27 console.log("sub2 " + val);
28 });
29
30 this.subject$.next("5");
31 this.subject$.complete();
32
33 this.subject$.error("err");
34
35 this.subject$.next("6");
36
37 this.subject$.subscribe(
38 val => console.log("Sub3 " + val),
39 err => console.error("sub3 " + err),
40 () => console.log("Sub3 Complete")
41 );
42 }
43 }
44
45
46 **Result **
47 Sub1 5
48 sub2 5
49 Sub1 Complete
50 Sub3 5
51 Sub3 Complete
52
Stackblitz
In the above example, all the subscribers will receive the value 5 including those who subscribe after the complete
event.
But if the AsyncSubject errors out, then all subscribers will receive an error notification and no value.
Angular Observable Subject Example Sharing Data Between Components
Leave a Comment / 4 minutes of reading / May 8, 2021
ReplaySubject, BehaviorSubject & AsyncSubject
Angular Global Styles

In this tutorial, we will show you how to use Subjects in Angular with examples. We learned What is Subjects in
Angular and different types of subjects like ReplaySubject, BehaviorSubject & AsyncSubject in Angular

Table of Contents
Angular Subject Example
Todo Service Using BehaviorSubject
TodoList Component
TodoAdd Component
References
Angular Subject Example
We will build a todo app. Our app has two components.
One is the Todo list component, which displays the list of todos. It also has the option to delete a todo
Another one is Todo add a component, which allows us to add a Todo item.
Both will communicate with each other via Service. Whenever a new todo is added, the service will notify the Todo
list component to update the lists using a observable
Code is available at StackBlitz
Todo Service Using BehaviorSubject
Create the todo.service.ts in the src\app folder.
todo.service.ts
1
2 import { Injectable } from "@angular/core";
3 import { BehaviorSubject } from "rxjs";
4
5 export interface Todo {
6 id: any;
7 value: string;
8 }
9
10 @Injectable()
11 export class TodoService {
12
13 private _todo = new BehaviorSubject<Todo[]>([]);
14 readonly todos$ = this._todo.asObservable();
15
16 private todos: Todo[] = [];
17 private nextId = 0;
18
19 constructor() {}
20
21 loadAll() {
22 this.todos = [];
23 this._todo.next(this.todos);
24 }
25
26 create(item: Todo) {
27 item.id = ++this.nextId;
28 this.todos.push(item);
29 this._todo.next(Object.assign([], this.todos));
30 }
31
32 remove(id: number) {
33 this.todos.forEach((t, i) => {
34 if (t.id === id) {
35 this.todos.splice(i, 1);
36 }
37 this._todo.next(Object.assign([], this.todos));
38 });
39 }
40 }
41
42
Here, we create BehaviorSubject of type Todo[]. Behavior expects us to provide an initial value. We assign an empty
array. The BehaviorSubject will always emit the latest list of Todo items as an array. We can also use Subject here.
But the advantage of BehaviorSubject is that the late subscribers will always receive the latest list of Todo items
immediately on the subscription. We do not have to call the next method.
1
2 private _todo$ = new BehaviorSubject<Todo[]>([]);
3
4
Also, it is advisable not to expose the BehaviorSubject outside the service. Hence we convert it to
normal Observable and return it. This is because the methods like next, complete or error do not exist on normal
observable. It will ensure that the end-user will not accidentally call them and mess up with it
1
2 readonly todos$ = this._todo.asObservable();
3
The todos will store the todo items in memory. We use the nextId to create the id of the Todo item.
1
2 private todos: Todo[] = [];
3 private nextId = 0;
4
Create pushes the new item to the todos list. Here we use the next method to push the todos list to all the
subscribers. Note that we use the Object.assign to create a new copy of the todos and push it to the subscribers. This
will protect our original copy of the todos list from accidental modification by the user.
1
2 create(item: Todo) {
3 item.id = ++this.nextId;
4
5 //Update database
6 this.todos.push(item);
7 this._todo$.next(Object.assign([], this.todos));
8 }
9
Remove method removes the Todo item based on id and pushes the new list to subscribers.
1
2 remove(id: number) {
3 this.todos.forEach((t, i) => {
4 if (t.id === id) {
5 this.todos.splice(i, 1);
6 }
7 this._todo$.next(Object.assign([], this.todos));
8 });
9 }
10
TodoList Component
TodoListComponent displays the list of Todo items.
todo-list.component.ts
1
2 import { Component, OnInit } from "@angular/core";
3 import { FormBuilder, FormGroup, Validators } from "@angular/forms";
4 import { Observable } from "rxjs";
5 import { map } from "rxjs/operators";
6
7 import { Todo, TodoService } from "./todo.service";
8
9 @Component({
10 selector: "app-todo",
11 template: `
12 <div *ngFor="let todo of (todos$ | async)">
13 {{ todo.id }} {{ todo.value }}
14 <button (click)="deleteTodo(todo.id)">x</button>
15 </div>
16 `
17 })
18 export class TodoListComponent implements OnInit {
19 todos$: Observable<Todo[]>;
20
21 constructor(private todoService: TodoService) {}
22
23 ngOnInit() {
24 this.todos$ = this.todoService.todos$;
25 }
26
27 deleteTodo(todoId: number) {
28 this.todoService.remove(todoId);
29 }
30 }
31
32
We inject todoService
1
2 constructor(private todoService: TodoService) {}
3
And get hold of a reference to the todo$ observable.
1
2 this.todos$ = this.todoService.todos$;
3
We use the async pipes to subscribe to the todos$ observable. No need to worry about unsubscribing the
observable as angular handles it when using async pipes
1
2 <div *ngFor="let todo of (todos$ | async)">
3 {{ todo.id }} {{ todo.value }}
4 <button (click)="deleteTodo(todo.id)">x</button>
5 </div>
6
deleteTodo deletes the Todo item by calling the remove method of the todoService
1
2 deleteTodo(todoId: number) {
3 this.todoService.remove(todoId);
4 }
5
TodoAdd Component
We use TodoAddComponent to add a new Todo item
todo-add.component.ts
1
2 import { Component, OnInit } from "@angular/core";
3 import { FormBuilder, FormGroup, Validators } from "@angular/forms";
4 import { Observable } from "rxjs";
5 import { map } from "rxjs/operators";
6
7 import { Todo, TodoService } from "./todo.service";
8
9 @Component({
10 selector: "app-todo-add",
11 template: `
12 <div>
13 <form [formGroup]="todoForm" (submit)="onSubmit()">
14 <p>
15 <input type="text" id="value" name="value" formControlName="value" />
16 </p>
17
18 <button type="submit">Add Item</button><br />
19 </form>
20 </div>
21 `
22 })
23 export class TodoAddComponent implements OnInit {
24 todos$: Observable<Todo[]>;
25 todoForm: FormGroup;
26
27 constructor(
28 private todoService: TodoService,
29 private formBuilder: FormBuilder
30 ) {
31 this.todoForm = this.formBuilder.group({
32 id: [""],
33 value: ["", Validators.required]
34 });
35 }
36
37 ngOnInit() {
38 this.todos$ = this.todoService.todos$;
39 }
40
41 onSubmit() {
42 this.todoService.create(this.todoForm.value);
43 this.todoForm.get("value").setValue("");
44 }
45 }
46
47
First inject todoService
1
2 constructor(
3 private todoService: TodoService,
4 private formBuilder: FormBuilder
5 )
6
We get hold of the todos$ observable. We are not doing anything with it But you can subscribe to it to get the latest
list of Todo items.
1
2 ngOnInit() {
3 this.todos$ = this.todoService.todos$;
4 }
5
onSubmit method creates a new Todo item by calling the create method of the todoService.
1
2 onSubmit() {
3 this.todoService.create(this.todoForm.value);
4 this.todoForm.get("value").setValue("");
5 }
6
app.component.html
1
2 <app-todo-add></app-todo-add>
3 <app-todo></app-todo>
4

Understanding ViewChild, ViewChildren & Querylist in Angular


2 Comments / 9 minutes of reading / September 29, 2020
HostBinding & HostListener
Elementref

The ViewChild or ViewChildren decorators are used to Query and get the reference of the DOM element in the
Component. ViewChild returns the first matching element and ViewChildren returns all the matching elements as
a QueryList of items. We can use these references to manipulate element properties in the component.

To Query a DOM element(s), we must supply the query selector, which can be a string or a type as the first argument
to the ViewChild or ViewChildren. The argument static determines whether the query is performed, before or after
the change detection. The read option allows us to query a different token rather than the default and is useful when
the element is associated with multiple types. We will learn all these in this tutorial.
Table of Contents
ViewChild
Syntax
ViewChild Examples
Injecting Component or Directive Reference
Using Template Reference Variable
Injecting HTML Element Using ElementRef
Multiple Instances
ViewChild returns Undefined
Using Static Option in ViewChild
Using the Read Option in ViewChild
Injecting a Provider from the Child Component
Injecting TemplateRef
ViewChildren
Syntax
QueryList
ViewChildren Example
Listening for QueryList Changes
Reference
ViewChild
The ViewChild query returns the first matching element from the DOM and updates the component variable on
which we apply it.
Syntax
The Syntax of the viewChild is as shown below.
1
2 ViewChild(selector: string | Function | Type<any>, opts: { read?: any; static: boolean; }): any
3
We apply the viewChild decorator on a Component Property. It takes two arguments. A selector and opts.
selector: can be a string, a type or a function that returns a string or type. The change detector looks for the first
element that matches the selector and updates the component property with the reference to the element. If the
DOM changes and a new element matches the selector, the change detector updates the component property.
opts: has two options.
static Determines when the query is resolved. True is when the view is initialized (before the first change detection)
for the first time. False if you want it to be resolved after every change detection
read: Use it to read the different token from the queried elements.
ViewChild Examples
Now, let us learn ViewChild using few examples.
Injecting Component or Directive Reference
One of the use cases of ViewChild is to get the reference of the Child Component in the Parent Component and
manipulate its properties. This is one of the ways by which the Parent can communicate with the child components.
For Example consider the following ChildComponent. It has two methods. Increment & Decrement.

BEST ANGULAR BOOKS


The Top 8 Best Angular Books, which helps you to get started with Angular
1
2 import { Component } from '@angular/core';
3
4 @Component({
5 selector: 'child-component',
6 template: `<h2>Child Component</h2>
7 current count is {{ count }}
8 `
9 })
10 export class ChildComponent {
11 count = 0;
12
13 increment() {
14 this.count++;
15 }
16 decrement() {
17 this.count--;
18 }
19 }
20
We can use the ViewChild in the parent component to get the reference to the ChildComponent
1
2 @ViewChild(ChildComponent, {static:true}) child: ChildComponent;
3
In the code above, the ViewChild looks for the first occurrence of the ChildComponent in the view and updates
the child variable. Now we can invoke the methods Increment & Decrement of the ChildComponent from the Parent.
The complete code is as shown below.
1
2 import { Component, ViewChild } from '@angular/core';
3 import { ChildComponent } from './child.component';
4
5 @Component({
6 selector: 'app-root',
7 template: `
8 <h1>{{title}}</h1>
9 <p> current count is {{child.count}} </p>
10 <button (click)="increment()">Increment</button>
11 <button (click)="decrement()">decrement</button>
12 <child-component></child-component>
13 `,
14 styleUrls: ['./app.component.css']
15 })
16 export class AppComponent {
17 title = 'Parent calls an @ViewChild()';
18
19 @ViewChild(ChildComponent, {static:true}) child: ChildComponent;
20
21 increment() {
22 this.child.increment();
23 }
24
25 decrement() {
26 this.child.decrement();
27 }
28
29 }
30
Using Template Reference Variable
You can make use of Template Reference Variable instead of the component type.
For Example, you can assign a Template Reference Variable to a component.
1
2 <child-component #child></child-component>
3
and then use it in the ViewChild query to get the reference to the component.
1
2 @ViewChild("child", { static: true }) child: ChildComponent;
3
Injecting HTML Element Using ElementRef
The Viewchild can also be used to query HTML elements.
First, assign a Template variable (#para in the example below) to the HTML element. You can then use
the ViewChild to query the element.
ViewChild returns a ElementRef, which is nothing but a wrapper around the native HTML element.
1
2 import {AfterViewInit, Component, ElementRef, ViewChild} from '@angular/core';
3
4 @Component({
5 selector: 'htmlelement',
6 template: `
7 <p #para>Some text</p>
8 `,
9 })
10 export class HTMLElementComponent implements AfterViewInit {
11
12 @ViewChild('para',{static:false}) para: ElementRef;
13
14 ngAfterViewInit() {
15 console.log(this.para.nativeElement.innerHTML);
16 this.para.nativeElement.innerHTML="new text"
17 }
18 }
19
Multiple Instances
There could be multiple instances of the same component or element in the Template.
1
2 <child-component></child-component>
3 <child-component></child-component>
4
The ViewChild always returns the first component.
1
2 @ViewChild(ChildComponent, {static:true}) child: ChildComponent;
3
To get all the instances of the Child Component, we can make use of the ViewChildren, which we cover later in this
tutorial.
ViewChild returns Undefined
ViewChild Returning undefined is one of the common errors, we encounter when we use them.
The error is due to the fact that we try to use the value, before the ViewChild initializes it.
For Example, the code below results in Cannot read property 'increment' of undefined. i.e. the component’s view is
not yet initialized when the constructor is run. Hence, the Angular yet to update child variable with the reference to
the ChildComponet.
1
2 export class AppComponent {
3 title = 'Parent calls an @ViewChild()';
4
5 @ViewChild(ChildComponent, {static:true}) child: ChildComponent;
6
7 constructor() {
8 this.child.increment()
9 }
10
11 }
12
13 //
14 Cannot read property 'increment' of undefined
15
The solution is to wait until the Angular Initializes the View. Angular raises the AfterViewInit life cycle hook once it
completes the View Initialization. So we can use the ngAfterViewInit to access the child variable.
1
2 ngAfterViewInit() {
3 this.child.increment()
4 }
5
Now, the code does not give any errors.
The above code will also work with the ngOnInit Life cycle hook. But it is not guaranteed to work all the time as the
Angular might not initialize all parts of the view, before raising the ngOnInit hook. Hence it is always better to use
the ngAfterViewInit hook.
Also, when ViewChild updates the values also depends on the static option
Using Static Option in ViewChild
We used the {static:true} in the above code.
The static option determines the timing of the ViewChild query resolution.
static:true will resolves ViewChild before any change detection is run.
static:false will resolves it after every change detection run.
The value of the static becomes important when the child is rendered dynamically. For Example inside
a ngIf or ngSwitch etc.
For Example consider the following code, where we have moved the child-component inside the ngIf.
1
2 //child.component.html
3
4 <h1>ViewChild Example</h1>
5
6 <input type="checkbox" id="showCounter" name="showCounter" [(ngModel)]="showCounter">
7
8 <ng-container *ngIf="showCounter">
9
10 <p> current count is {{child?.count}} </p>
11
12 <button (click)="increment()">Increment</button>
13 <button (click)="decrement()">decrement</button>
14
15 <child-component></child-component>
16
17 </ng-container>
18

1
2 //child.component.ts
3
4 import { Component, ViewChild, AfterViewInit, OnInit, ChangeDetectorRef } from '@angular/core';
5 import { ChildComponent } from './child.component';
6
7 @Component({
8 selector: 'app-root',
9 templateUrl: 'app.component.html' ,
10 styleUrls: ['./app.component.css']
11 })
12 export class AppComponent {
13 title = 'ViewChild Example)';
14
15 showCounter: boolean = true
16
17 @ViewChild(ChildComponent, { static: true }) child: ChildComponent;
18
19 increment() {
20 this.child.increment();
21 }
22
23 decrement() {
24 this.child.decrement();
25 }
26
27 }
28
The above code results in a TypeError: Cannot read property 'increment' of undefined. The error occurs even if we
assign true to showCounter
Because in the above case Angular does not render the child component immediately. But after the first change
detection which detects the value of showCounter and renders the child component.
Since we used static: true, the angular will try to resolve the ViewChild before the first change detection is run.
Hence the child variable always will be undefined.
Now, change the static: false. Now the code will work correctly. I.e because after every change detection the Angular
updates the ViewChild.
Using the Read Option in ViewChild
A Single element can be associated with multiple types.
For Example, consider the following code. #nameInput template variable is now associated with
both input & ngModel
1
2 <input #nameInput [(ngModel)]="name">
3
The viewChild code below, returns the instance of the input element as elementRef.
1
2 @ViewChild('nameInput',{static:false}) nameVar;
3
If we want to get the instance of the ngModel, then we use the Read token and ask for the type.
1
2 @ViewChild('nameInput',{static:false, read: NgModel}) inRef;
3
4 @ViewChild('nameInput',{static:false, read: ElementRef}) elRef;
5 @ViewChild('nameInput', {static:false, read: ViewContainerRef }) vcRef;
6
Every element in Angular is always has a ElementRef and ViewContainerRef associated with it. If the element is a
component or directive then there is always a component or directive instance. You can also apply more than one
directive to an element.
The ViewChild without read token always returns the component instance if it is a component. If not it returns
the elementRef.
Injecting a Provider from the Child Component
You can also inject the services provided in the child component.
1
2 import { ViewChild, Component } from '@angular/core';
3
4 @Component({
5 selector: 'app-child',
6 template: `<h1>Child With Provider</h1>`,
7 providers: [{ provide: 'Token', useValue: 'Value' }]
8 })
9
10 export class ChildComponent{
11 }
12
And in the Parent component, you can access the provider using the read property.
1
2 import { ViewChild, Component } from '@angular/core';
3
4 @Component({
5 selector: 'app-root',
6 template: `<app-child></app-child>`,
7 })
8
9 export class AppComponent{
10 @ViewChild(ChildComponent , { read:'Token', static:false } ) childToken: string;
11 }
12
Injecting TemplateRef
You can access the TemplateRef as shown below
1
2 <ng-template #sayHelloTemplate>
3 <p> Say Hello</p>
4 </ng-template>
5
Component code
1
2 @ViewChild("sayHelloTemplate", { static: false }) tempRef: TemplateRef;
3
ViewChildren
ViewChildren decorator is used to getting the list of element references from the View.
ViewChildren is different from the ViewChild. ViewChild always returns the reference to a single element. If there are
multiple elements the ViewChild returns the first matching element,
ViewChildren always returns all the elements as a QueryList. You can iterate through the list and access each
element.
Syntax
The Syntax of the viewChildren is as shown below. It is very much similar to syntax of viewChild except for
the static option.
1
2 ViewChildren(selector: string | Function | Type<any>, opts: { read?: any; }): any
3
The ViewChildren is always resolved after the change detection is run. i.e why it does not have static option. And also
you cannot refer to it in the ngOnInit hook as it is yet to initialize.
QueryList
The QueryList is the return type of ViewChildren and contentChildren .
QueryList stores the items returned by the viewChildren or contentChildren in a list.
The Angular updates this list, whenever the state of the application change. It does it on each change detection.
The QueryList also Implements an iterable interface. Which means you can iterate over it using for (var i of items) or
use it with ngFor in template *ngFor="let i of items".
Changes can be observed by subscribing to the changes Observable.
You can use the following methods & properties.
first: returns the first item in the list.
last: get the last item in the list.
length: get the length of the items.
changes: Is an observable. It emits a new value, whenever the Angular adds, removes or moves the child elements.
It also supports JavaScript array methods like map(), filter() , find(), reduce(), forEach(), some(). etc
ViewChildren Example
In the example below, we have three input elements all using the ngModel directive
We use the ViewChildren to get the QueryList of all input elements
Finally, we can use the this.modelRefList.forEach to loop through the QueryList and access each element.
1
2 import { ViewChild, Component, ViewChildren, QueryList, AfterViewInit } from '@angular/core';
3 import { NgModel } from '@angular/forms';
4
5 @Component({
6 selector: 'app-viewchildren1',
7 template: `
8 <h1>ViewChildren Example</h1>
9
10 <input name="firstName" [(ngModel)]="firstName">
11 <input name="midlleName" [(ngModel)]="middleName">
12 <input name="lastName" [(ngModel)]="lastName">
13
14 <button (click)="show()">Show</button>
15
16 `,
17 })
18
19 export class ViewChildrenExample1Component {
20
21 firstName;
22 middleName;
23 lastName;
24
25 @ViewChildren(NgModel) modelRefList: QueryList<NgModel>;
26
27 show() {
28
29 this.modelRefList.forEach(element => {
30 console.log(element)
31 //console.log(element.value)
32 });
33 }
34 }
35
Listening for QueryList Changes
We can subscribe to the changes observable to find if any new elements are added/removed or moved.
In the example below, we have included ngIf directive to hide/show the input elements.
We subscribe to the changes observable in the component class. Every time we use the ngIf to hide or add the
component, the changes observable emits the latest QueryList.
1
2 import { ViewChild, Component, ViewChildren, QueryList, AfterViewInit } from '@angular/core';
3 import { NgModel } from '@angular/forms';
4
5 @Component({
6 selector: 'app-viewchildren2',
7 template: `
8 <h1>ViewChildren Example</h1>
9
10 <input *ngIf="showFirstName" name="firstName" [(ngModel)]="firstName">
11 <input *ngIf="showMiddleName" name="midlleName" [(ngModel)]="middleName">
12 <input *ngIf="showlastName" name="lastName" [(ngModel)]="lastName">
13
14
15 <input type="checkbox" id="showFirstName" name="showFirstName" [(ngModel)]="showFirstName">
16 <input type="checkbox" id="showMiddleName" name="showMiddleName" [(ngModel)]="showMiddleName">
17 <input type="checkbox" id="showlastName" name="showlastName" [(ngModel)]="showlastName">
18
19 <button (click)="show()">Show</button>
20
21 `,
22
23 })
24
25 export class ViewChildrenExample2Component implements AfterViewInit {
26
27 firstName;
28 middleName;
29 lastName;
30
31 showFirstName=true;
32 showMiddleName=true;
33 showlastName=true;
34
35 @ViewChildren(NgModel) modelRefList: QueryList<NgModel>;
36
37 ngAfterViewInit() {
38
39 this,this.modelRefList.changes
40 .subscribe(data => {
41 console.log(data)
42 }
43 )
44 }
45
46
47 show() {
48 this.modelRefList.forEach(element => {
49 console.log(element)
50 //console.log(element.value)
51 });
52
53 }
54 }
55
Reference
ViewChild API
ViewChildren API
QueryList API
ElementRef API
ViewContainerRef API
Read More
ngModel
ElementRef
ElementRef in Angular
Leave a Comment / 4 minutes of reading / May 16, 2021
Viewchild, viewchildren & querylist
Renderer2

Angular ElementRef is a wrapper around a native DOM element (HTML element) object. It contains the
property nativeElement, which holds the reference to the underlying DOM object. We can use it to manipulate the
DOM. We use the ViewChild to get the ElementRef of an HTML element in the component class. Angular also
inject ElementRef of the Host element of the component or directive when you request for it in the constructor. In
this tutorial, let us explore how to use ElementRef to get the reference of an HtmlElement & manipulate the DOM in
Angular Applications.

00:10/03:27
Table of Contents
ElementRef
Getting ElementRef in Component Class
Read token
ElementRef Example
ElementRef in Custom Directive
Use with caution
ElementRef & XSS Injection Attack
Reference
ElementRef
The DOM objects are created and maintained by the Browser. They represent the structure and content of the
Document. In a Vanilla JavaScript code, we access these DOM objects to manipulate the View. We can create and
build documents, navigate their structure, and add, modify, or delete elements and content.
Angular provides a lot of tools & techniques to manipulate the DOM. We can add/remove components. It provides a
lot of directives like Class Directive or Style directive. to Manipulate their styles etc.
We may still need to access the DOM element on some occasions. This is where the ElementRef comes into the
picture.
Getting ElementRef in Component Class
To manipulate the DOM using the ElementRef, we need to get the reference to the DOM element in
the component/directive.
To get the reference to DOM elements in the component
Create a template reference variable for the element in the component/directive.
Use the template variable to inject the element into component class using the ViewChild or ViewChildren.
To get the DOM element hosting the component/directive
Ask for ElementRef in the constructor (Angular Dependency injection), the Angular will inject the reference element
hosting the component/directive.

BEST ANGULAR BOOKS


The Top 8 Best Angular Books, which helps you to get started with Angular
For Example, in the following code, the variable hello refers to the HTML element div.
1
2 <div #hello>Hello Angular</div>
3
hello is the Template Reference variable, which we can use in the Template.
In the Component class, we use the ViewChild to inject the hello element. The Angular injects the hello as a type
of ElementRef.
1
2 @ViewChild('hello', { static: false }) divHello: ElementRef;
3
Read token
Consider the following example
1
2 <input #nameInput [(ngModel)]="name">
3
The nameInput Template Reference Variable now binds to the input element. But at the same time, we
have ngModel directive applied to it.
Under such circumstance, we can use the read token to let angular know that we need ElementRef reference as
shown below
1
2 //ViewChild returns ElementRef i.e. input HTML Element
3
4 @ViewChild('nameInput',{static:false, read: ElementRef}) elRef;
5
6
7 //ViewChild returns NgModel associated with the nameInput
8 @ViewChild('nameInput',{static:false, read: NgModel}) inRef;
9
10
ElementRef Example
Once we have the ElementRef , we can use the nativeElement property to manipulate the DOM as shown below.
We need to wait for Angular to Initializes the View, before accessing the ViewChild variables. Hence we wait until
the AfterViewInit life cycle hook, to start making use of the variable.
1
2 import { Component,ElementRef, ViewChild, AfterViewInit } from '@angular/core';
3
4 @Component({
5 selector: 'app-root',
6 template: '<div #hello>Hello</div>'
7 styleUrls: ['./app.component.css']
8 })
9 export class AppComponent implements AfterViewInit {
10
11 @ViewChild('hello', { static: false }) divHello: ElementRef;
12
13 ngAfterViewInit() {
14 this.divHello.nativeElement.innerHTML = "Hello Angular";
15 }
16
17 }
18
You can manipulate the DOM very easily.
1
2 ngAfterViewInit() {
3 this.divHello.nativeElement.innerHTML = "Hello Angular";
4 this.divHello.nativeElement.className="someClass";
5 this.divHello.nativeElement.style.backgroundColor="red";
6 }
7
8
ElementRef in Custom Directive
One of the use case for ElementRef is the Angular directive. We learned how to create a custom directive in Angular.
The following is the code for the ttClass custom attribute directive.
1
2 import { Directive, ElementRef, Input, OnInit } from '@angular/core'
3
4 @Directive({
5 selector: '[ttClass]',
6 })
7 export class ttClassDirective implements OnInit {
8
9 @Input() ttClass: string;
10
11 constructor(private el: ElementRef) {
12 }
13
14 ngOnInit() {
15 this.el.nativeElement.classList.add(this.ttClass);
16 }
17
18 }
19
Note that we are injecting the ElementRef in the constructor. Whenever we ask for the ElementRef in the
constructor, the Angular will inject the reference to the host DOM element of the directive.
Use with caution
[From the Angular Documents]
Use this API as the last resort when direct access to DOM is needed. Use templating and data-binding provided by
Angular instead. Alternatively, you can take a look at Renderer2 which provides API that can safely be used even
when direct access to native elements is not supported.
Relying on direct DOM access creates tight coupling between your application and rendering layers which will make
it impossible to separate the two and deploy your application into a web worker.
ElementRef & XSS Injection Attack
Improper use of ElementRef can result in an XSS Injection attack. For Example in the following code, we are injecting
a script using the elementRef. When the component containing such code runs, the script is executed
1
2 constructor(private elementRef: ElementRef) {
3 const s = document.createElement('script');
4 s.type = 'text/javascript';
5 s.textContent = 'alert("Hello World")';
6 this.elementRef.nativeElement.appendChild(s);
7 }
8
Renderer2 Example: Manipulating DOM in Angular
3 Comments / 8 minutes of reading / January 3, 2021
ElementRef
ContentChild & ContentChildren

The Renderer2 allows us to manipulate the DOM elements, without accessing the DOM directly. It provides a layer of
abstraction between the DOM element and the component code. Using Renderer2 we can create an element, add a
text node to it, append child element using the appendchild method., etc. We can also add or remove styles, HTML
attributes, CSS Classes & properties, etc. We can also attach and listen to events etc.

Table of Contents
Why not ElementRef?
Using Renderer2
Setting & Removing Styles (setStyle & removeStyle)
Adding / Removing CSS Classes (addClass & removeClass)
Setting or Remove Attributes (setAttribute & removeAttribute)
Setting Property (setProperty)
AppendChild
Insert Text Element (CreateText & appendChild)
Creating new Element (createElement & appendChild)
InsertBefore
Insert Comment
ParentNode & NextSibling
SelectRootElement
Listen to DOM events
Reference
Why not ElementRef?
We can use the nativeElement property of the ElelemtRef to manipulate the DOM. We learned this in our last
tutorial on ElementRef. The nativeElement Property contains the reference to the underlying DOM object. This gives
us direct access to the DOM, bypassing the Angular. There is nothing wrong with using it, but it is not advisable for
the following reasons.
Angular keeps the Component & the view in Sync using Templates, data binding & change detection, etc. All of them
are bypassed when we update the DOM Directly.
DOM Manipulation works only in Browser. You will not able to use the App in other platforms like in a web worker,
in Server (Server-side rendering), or in a Desktop, or in the mobile app, etc where there is no browser.
The DOM APIs do not sanitize the data. Hence it is possible to inject a script, thereby, opening our app an easy target
for the XSS injection attack.
Using Renderer2
First import it from the @angular/core
1
2 import {Component, Renderer2, ElementRef, ViewChild, AfterViewInit } from '@angular/core';
3
inject it into the component
1
2 constructor(private renderer:Renderer2) {
3}
4
Use ElementRef & ViewChild to get the reference to the DOM element, which you want to manipulate.
1
2 @ViewChild('hello', { static: false }) divHello: ElementRef;
3
Use the methods like setProperty , setStyle etc to change the property, styles of the element as shown below.
1
2 this.renderer.setProperty(this.divHello.nativeElement,'innerHTML',"Hello Angular")
3
4 this.renderer.setStyle(this.divHello.nativeElement, 'color', 'red');
5
Code Example
Setting & Removing Styles (setStyle & removeStyle)
Use the setStyle & RemoveStyle to add or remove the styles. It accepts four argument.
The first argument is the element to which we want to apply the style. name of the styles is the second argument.
The value of the style is the third argument. The last argument is Flags for style variations
1
2 abstract setStyle(el: any, style: string, value: any, flags?: RendererStyleFlags2): void
3
4 abstract removeStyle(el: any, style: string, flags?: RendererStyleFlags2): void
5
Example
1
2 //Template
3
4 <div #hello>Hello !</div>
5
6
7 //Component
8 @ViewChild('hello', { static: false }) divHello: ElementRef;
9
10
11 setStyle() {
12 this.renderer.setStyle(this.divHello.nativeElement, 'color', 'blue');
13 }
14
15
16 removeStyle() {
17 this.renderer.removeStyle(this.divHello.nativeElement, 'color');
18 }
19
Use the last option RendererStyleFlags2 to add the !important or to make use of DashCase
Adding / Removing CSS Classes (addClass & removeClass)
Use the methods addClass / removeClass to add or remove classes.
Syntax
1
2 abstract addClass(el: any, name: string): void
3
4
5 abstract removeClass(el: any, name: string): void
6
Example
1
2 //Template
3
4 <div #hello>Hello !</div>
5
6
7
8 //Component
9 @ViewChild('hello', { static: false }) divHello: ElementRef;
10
11 addClass() {
12 this.renderer.addClass(this.divHello.nativeElement, 'blackborder' );
13 }
14
15 removeClass() {
16 this.renderer.removeClass(this.divHello.nativeElement, 'blackborder');
17 }
18
19
Setting or Remove Attributes (setAttribute & removeAttribute)
We can add remove attributes using the setAttribute & removeAttribute
1
2 setAttribute(el: any, name: string, value: string, namespace?: string): void
3
4 removeAttribute(el: any, name: string, namespace?: string): void
5
Example
1
2 //Template
3
4 <h2>Add/ Remove Attributes </h2>
5 <input #inputElement type='text'>
6 <button (click)="addAttribute()">Set Attribute</button>
7 <button (click)="removeAttribute()">Remove Attribute</button>
8
9
10
11 //Component
12
13 @ViewChild('inputElement', { static: false }) inputElement: ElementRef;
14
15
16 addAttribute() {
17 this.renderer.setAttribute(this.inputElement.nativeElement, 'value', 'name' );
18 }
19
20
21 removeAttribute() {
22 this.renderer.removeAttribute(this.inputElement.nativeElement, 'value');
23 }
24
25
Setting Property (setProperty)
Set any property of a DOM element using the setProperty method.
1
2 setProperty(el: any, name: string, value: any): void
3

1
2 setProperty() {
3 this.renderer.setProperty(this.divHello.nativeElement,'innerHTML',"Hello Angular")
4}
5
AppendChild
Use the appendChild to append a new element (child element) to any existing element (parent element).
1
2 appendChild(parent: any, newChild: any): void
3
It accepts two arguments. The first argument is the parent node, where we want to append a new child node. The
second argument is the child node, which you want to add.
The next two examples, shows how to use appendChild.
Insert Text Element (CreateText & appendChild)
CreateText allow us to add text to the DOM.
Example
The following template has a empty div ( #divCreateText)
1
2 //Template
3
4 <h2>Create Text Example</h2>
5 <div #divCreateText> </div>
6 <button (click)="createText()">Create Text</button>
7
Use the ViewChild to inject the reference to the divCreateText in the component.
1
2 @ViewChild('divCreateText', { static: false }) divCreateText: ElementRef;
3
Use the createText method the create text node. At this point it is not added to the DOM.
1
2 const text = this.renderer.createText('Example of Create Text');
3
Use the appendChild method to add it to an existing element (divCreateText).
1
2 this.renderer.appendChild(this.divCreateText.nativeElement, text);
3
Creating new Element (createElement & appendChild)
We can easily create a new element using the createElement & appendChild.
createElement creates a new element, but does not insert it into the DOM. To insert into the DOM, we need to add
it to an element, which already exists in the DOM using appendChild method.
The following example shows how to create a new element and append to the DOM.
First, we inject ElementRef in the constructor. This will inject the DOM element hosting the component/directive.
1
2 constructor(private el: ElementRef,
3 private renderer:Renderer2) {
4 }
5
Create a new div element using the method createElement('div'). It is not yet added to the DOM.
1
2 const div = this.renderer.createElement('div');
3
Make use of the createText('Inserted at bottom') to create a new text node.
1
2 const text = this.renderer.createText('Inserted at bottom');
3
Use appendChild to append the newly created text node to the div element. Note that div is not yet added to the
DOM.
1
2 this.renderer.appendChild(div, text);
3
Finally, we add the div element to an existing DOM element i.e. host element.
1
2 this.renderer.appendChild(this.div.nativeElement, div);
3
The complete code as under. The createElement2 appends the new child node a another div.
1
2 import { Component, Renderer2, OnInit, ElementRef, ViewChild, AfterViewInit, VERSION } from '@angular/core';
3
4 @Component({
5 selector: 'app-create-element',
6 templateUrl: './create-element.component.html',
7 styleUrls: ['./create-element.component.css']
8 })
9 export class CreateElementComponent {
10
11
12 @ViewChild('div', { static: false }) div: ElementRef;
13
14
15 constructor(private el: ElementRef,
16 private renderer:Renderer2) {
17 }
18
19
20 createElement() {
21 const div = this.renderer.createElement('div');
22 const text = this.renderer.createText('Inserted at bottom');
23
24 this.renderer.appendChild(div, text);
25 this.renderer.appendChild(this.el.nativeElement, div);
26 }
27
28
29 createElement2() {
30 const div = this.renderer.createElement('div');
31 const text = this.renderer.createText('Inserted inside div');
32
33 this.renderer.appendChild(div, text);
34 this.renderer.appendChild(this.div.nativeElement, div);
35 }
36
37 }
38
39

1
2 <h2>Renderer2 Create Element</h2>
3
4 <div #div style="border: 1px solid black;">
5 This is a div
6 </div>
7
8 <button (click)="createElement()">Create Element</button>
9 <button (click)="createElement2()">Create Element</button>
10
InsertBefore
We can also insert the new element, before an element in the DOM element using the insertBefore method. The
syntax of insertBefore as shown below.
1
2 insertBefore(parent: any, newChild: any, refChild: any): void
3
parent is the parent node. newChild is the new node, which you want to insert. refChild is the existing child node
before which newChild is inserted.
The following Example inserts a new element before div1.
1
2 <h1>Angular Renderer2 InsertBefore Example</h1>
3
4
5 <div #div1>
6 This is div 1
7 </div>
8
9 <div #div2>
10 This is div 2
11
12 <div #div3>
13 This is div 3
14 </div>
15
16 </div>
17
18
19
20 <button (click)="insertBeforeDiv1()" >Insert Before Div1</button>
21
22 <button (click)="insertBeforeDiv2()" >Insert Before Div2</button>
23
24 <button (click)="insertBeforeDiv3()" >Insert Before Div3</button>
25
First, use the ViewChild to get the reference to the div1. Inject ElementRef, which gives us the reference to the Host
DOM element.
Create a new div element using createElement. Add a text node to it using createText and append it to the div
Use the insertBefore method to add the div element
1
2 import { Component, OnInit, ViewChild, ElementRef, Renderer2 } from '@angular/core';
3
4 @Component({
5 selector: 'app-insert-before',
6 templateUrl: './insert-before.component.html',
7 styleUrls: ['./insert-before.component.css']
8 })
9 export class InsertBeforeComponent {
10
11 @ViewChild('div1', { static: false }) div1: ElementRef;
12 @ViewChild('div2', { static: false }) div2: ElementRef;
13 @ViewChild('div3', { static: false }) div3: ElementRef;
14
15
16 constructor(private renderer:Renderer2, private el:ElementRef) { }
17
18
19
20 insertBeforeDiv1() {
21 const div = this.renderer.createElement('div');
22 const text = this.renderer.createText('This Text is Inserted before the div1');
23 this.renderer.appendChild(div, text);
24
25 this.renderer.insertBefore(this.el.nativeElement,div,this.div1.nativeElement);
26 }
27
28
29
30 insertBeforeDiv2() {
31 const div = this.renderer.createElement('div');
32 const text = this.renderer.createText('This Text is Inserted before the div2');
33 this.renderer.appendChild(div, text);
34
35 this.renderer.insertBefore(this.el.nativeElement,div,this.div2.nativeElement);
36 }
37
38
39
40
41 insertBeforeDiv3() {
42 const div = this.renderer.createElement('div');
43 const text = this.renderer.createText('This Text is Inserted before the div3');
44 this.renderer.appendChild(div, text);
45
46 //Using parentNode to retrieve the Parent Node
47 this.renderer.insertBefore( this.renderer.parentNode(this.div3.nativeElement),div,this.div3.nativeElement);
48 }
49
50
51 }
52
Insert Comment
createComment creates comment node. It accepts comment as the argument. You can then use
the appendChild or insertBefore to insert it anywhere in the DOM.
1
2 createComment(value: string): any
3
ParentNode & NextSibling
ParentNode method returns the parent of a given node in the host element’s DOM.
1
2 //Returns the parent Node of div3
3 this.renderer.parentNode(this.div3.nativeElement);
4
nextSibling method returns the next sibling node of a given node in the host element’s DOM.
1
2 //Returns the next Sibling node of div2
3 this.renderer.nextSibling(this.div2.nativeElement);
4
SelectRootElement
We can also use the selectRoomElement to select a node element based on a selector.
Syntax
1
2 selectRootElement(selectorOrNode: any, preserveContent?: boolean)
3
The first argument is the selector or node. The Renderer2 uses the selector to search for the DOM element and
returns it.
The second argument is preserveContent. If no or undefined, the renderer2 will remove all the child nodes. If yes the
child nodes are not removed.
Example, consider the following template
1
2 <h1>Renderer2 selectRootElement Example</h1>
3
4 <div class="outerDiv" style="border: 1px solid black; padding :5px;">
5
6 <div class="div1" style="border: 1px solid black; margin :5px;">This is Div1</div>
7 <div class="div2" style="border: 1px solid black; margin :5px;">This is Div2</div>
8 <div class="div3" class="div3class" style="border: 1px solid black; margin :5px;">This is Div3</div>
9
10 </div>
11
12
The selectRootElement in the following example returns the element div1 , but it removes all the content it holds.
Because the second argument is false. Change false to true, then the renderer2 will not remove the content.
1
2 exampleDiv1() {
3 const e = this.renderer.selectRootElement('.div1',false);
4 }
5
Examples.
1
2 exampleDiv2() {
3 //Conent is always replaced. becuase preserveContent is false
4 const e = this.renderer.selectRootElement('.div2',false);
5 const t = this.renderer.createText('Content added to div2');
6 this.renderer.appendChild(e, t);
7
8 }
9
10 exampleDiv3() {
11 //Conent is always appended. becuase preserveContent is true
12 const e = this.renderer.selectRootElement('.div3',true);
13 const t = this.renderer.createText('Content added to div3');
14 this.renderer.appendChild(e, t);
15 }
16
Listen to DOM events
You can also, listen to DOM events using the listen method.
The listen method accepts three arguments. the first argument is the DOM element (target). The second argument is
the name of the event (eventName) and the third argument is the callback
1
2 abstract listen(target: any, eventName: string, callback: (event: any) => boolean | void): () => void
3
In the following example, we listen to the click event of a button.
1
2 //Component
3
4 import { Component, OnInit, ViewChild, ElementRef, Renderer2, AfterViewInit } from '@angular/core';
5
6 @Component({
7 selector: 'app-listen-events',
8 templateUrl: './listen-events.component.html',
9 styleUrls: ['./listen-events.component.css']
10 })
11 export class ListenEventsComponent implements AfterViewInit {
12
13 @ViewChild('hello', { static: false }) divHello: ElementRef;
14
15 Count=0
16 clicklistener;
17
18 constructor(private renderer:Renderer2) { }
19
20 ngAfterViewInit() {
21
22 this.clicklistener = this.renderer.listen(this.divHello.nativeElement, 'click', (evt) => {
23 this.Count++;
24 });
25
26 }
27
28 ngOnDestroy() {
29 this.clicklistener.unsubscribe()
30 }
31
32 }
33
Do not forget to unsubscribe to the this.clicklistener.unsubscribe()
1
2 //Template
3
4 <h1>Renderer2 Listen Events Example</h1>
5
6
7 <button #hello>hello</button>
8
9 Click Count {{Count}}
10

Table of Contents
What is Angular Directive
Component Directive
Structural Directives
Commonly used structural directives
ngFor
ngSwitch
ngIf
Attribute Directives
Commonly used Attribute directives
ngModel
ngClass
ngStyle
Building Custom Directives
Summary
What is Angular Directive
The Angular directive helps us to manipulate the DOM. You can change the appearance, behavior, or layout of a
DOM element using the Directives. They help you to extend HTML
There are three kinds of directives in Angular:
Component Directive
Structural directives
Attribute directives
Component Directive
Components are special directives in Angular. They are the directive with a template (view) We covered how to
create Components in Angular tutorial.
Structural Directives
Structural directives can change the DOM layout by adding and removing DOM elements. All structural Directives are
preceded by Asterix symbol
Commonly used structural directives
ngFor
The ngFor is an Angular structural directive, which repeats a portion of the HTML template once per each item from
an iterable list (Collection). The ngFor is similar to ngRepeat in AngularJS
Example of ngFor
1
2 <tr *ngFor="let customer of customers;">
3 <td>{{customer.customerNo}}</td>
4 <td>{{customer.name}}</td>
5 <td>{{customer.address}}</td>
6 <td>{{customer.city}}</td>
7 <td>{{customer.state}}</td>
8 </tr>
9
10
You can read more about the Angular ngFor Directive tutorial.
ngSwitch
The ngSwitch directive lets you add/remove HTML elements depending on a match expression. ngSwitch directive
used along with ngSwitchCase and ngSwitchDefault
The example of ngSwitch
1
2 <div [ngSwitch]="Switch_Expression">
3 <div *ngSwitchCase="MatchExpression1”> First Template</div>
4 <div *ngSwitchCase="MatchExpression2">Second template</div>
5 <div *ngSwitchCase="MatchExpression3">Third Template</div>
6 <div *ngSwitchCase="MatchExpression4">Third Template</div>
7 <div *ngSwitchDefault?>Default Template</div>
8 </div>
9
You can read more about the Angular ngSwitch Directive tutorial.
ngIf
The ngIf Directives is used to add or remove HTML elements based on an expression. The expression must return a
boolean value. If the expression is false then the element is removed, else the element is inserted
Example of ngIf
1
2 <div *ngIf="condition">
3 This is shown if condition is true
4 </div>
5
You can read more about Angular ngIf Directive tutorial.
Attribute Directives
An Attribute or style directive can change the appearance or behavior of an element.
Commonly used Attribute directives
ngModel
The ngModel directive is used the achieve the two-way data binding. We have covered ngModel directive in Data
Binding in Angular Tutorial
ngClass
The ngClass is used to add or remove the CSS classes from an HTML element. Using the ngClass one can create
dynamic styles in HTML pages
Example of ngClass
1
2 <div [ngClass]="'first second'">...</div>
3
ngStyle
ngStyle is used to change the multiple style properties of our HTML elements. We can also bind these properties to
values that can be updated by the user or our components.
Example of ngStyle
1
2 <div [ngStyle]="{'color': 'blue', 'font-size': '24px', 'font-weight': 'bold'}">
3 some text
4 </div>
5
Building Custom Directives
You can also build custom directives in Angular. The Process is to create a JavaScript class and apply
the @Directive attribute to that class. You can write the desired behavior in the class.

Angular ngFor Directive


2 Comments / 8 minutes of reading / February 20, 2022
Child Component in Angular
ngSwitch Directive

Angular ngFor directive iterates over a collection of data like an array, list, etc, and creates an HTML element for
each of the items from an HTML template. It helps us to build lists or tables to display tabular data in a nice way. In
this tutorial, we will look at the syntax and how to use ngFor to display a list of movies using example code.
The ngFor also exports several local variables like Index, First, Last, odd, even & trackby.etc. In this article, we will
learn the following

Use ngFor in a List Box


Learn to use it in a Table
Use it to display a nested array.
How to assign of exported values to the local variable
Format the odd & even rows of a table by assigning different classes to them.
Find the index of each element in the collection
Learn to use trackBy clause, which enhances the performance
Table of Contents
Syntax of ngFor
ngFor Example
Using ngFor
Nested Array
Local Variables
Finding the Index
Formatting odd & even rows
First and the Last element of a list
Track By
Example
References
Syntax of ngFor
The syntax for the ngFor is as shown below
1
2 <html-element ngFor="let <item> of <items>;”>
3 <html-Template></html-Template>
4 </html-element>
5
<html-element>:
is the element on which we apply ngFor directive. it repeats the <html-element> .. </html-element> for each item of
the collection.
*ngFor :
The syntax starts with *ngFor. The * here tells us that ngFor is an Angular structural directive.
let <item> of <items>;
item is the Template input variable. It represents the currently iterated item from the <items>. <items> is
a collection, which we need to show to the user. It is usually a property on your component class and can be
anything that you can iterate over. (Usually an array)
The scope of the item is within the <html-element>..</html-element>. You can access it anywhere within that, but
not outside of it.
ngFor Example
Now let us see how to use ngFor using an example.
Create a new angular Application. If you are new to angular, then you should read Angular create a new project. We
are using bootstrap 4 to style our application. Hence you can add the following line to index.html

1 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"


2 integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
3 crossorigin="anonymous">

Open the app.component.ts and add the following code. The code contains a list of Top 10 movies. Let us build a
template to display the movies using ngFor.
1
2 import { Component } from '@angular/core';
3
4 @Component({
5 selector: 'app-root',
6 templateUrl: './app.component.html',
7 })
8 export class AppComponent {
9 title: string ="Top 5 Movies" ;
10
11
12 movies: Movie[] =[
13
14 {title:'Zootopia',director:'Byron Howard, Rich Moore',cast:'Idris Elba, Ginnifer Goodwin, Jason
15 Bateman',releaseDate:'March 4, 2016'},
16 {title:'Batman v Superman: Dawn of Justice',director:'Zack Snyder',cast:'Ben Affleck, Henry Cavill, Amy
17 Adams',releaseDate:'March 25, 2016'},
18 {title:'Captain American: Civil War',director:'Anthony Russo, Joe Russo',cast:'Scarlett Johansson, Elizabeth Olsen,
19 Chris Evans',releaseDate:'May 6, 2016'},
20 {title:'X-Men: Apocalypse',director:'Bryan Singer',cast:'Jennifer Lawrence, Olivia Munn, Oscar
21 Isaac',releaseDate:'May 27, 2016'},
22 {title:'Warcraft',director:'Duncan Jones',cast:'Travis Fimmel, Robert Kazinsky, Ben Foster',releaseDate:'June 10,
23 2016'},
]

24
}
25
26
class Movie {
27
title : string;
28
director : string;
29
cast : string;
30
releaseDate : string;
}

Source code
Using ngFor
To use ngFor,
Create a block of HTML elements, which can display a single movie.
Use the ngFor to repeat the block for each movie in the movies.
Open the app.component.html and add the following code.
1
2 <h1> {{title}} </h1>
3
4 <ul>
5 <li *ngFor="let movie of movies">
6 {{ movie.title }} - {{movie.director}}
7 </li>
8 </ul>
9
10
Source code
We use the ul to display the movies. The li element displays a single movie. We need to repeat the li for each movie.
Hence we apply the ngFor on the li element.
let movie of movies will iterate over the movies collection, which is a property on the component class. movie is
the Template input variable, which represents the currently iterated movie from the collection. We use Angular
Interpolation to display the movie title & name of the director
Here is the output

The Angular generates the following code. You can see li element for every movie.
1
2 <ul _ngcontent-gop-c0="">
3 <li _ngcontent-gop-c0=""> Zootopia - Byron Howard, Rich Moore </li>
4 <li _ngcontent-gop-c0=""> Batman v Superman: Dawn of Justice - Zack Snyder </li>
5 <li _ngcontent-gop-c0=""> Captain American: Civil War - Anthony Russo, Joe Russo </li>
6 <li _ngcontent-gop-c0=""> X-Men: Apocalypse - Bryan Singer </li>
7 <li _ngcontent-gop-c0=""> Warcraft - Duncan Jones </li>
8 </ul>
9
Similarly, you can use the table element to display the movies as shown below. Here we need to repeat
the tr element for each movie. Hence apply the directive on tr
1
2 <div class='panel panel-primary'>
3 <div class='panel-heading'>
4 {{title}}
5 </div>
6
7 <div class='panel-body'>
8 <div class='table-responsive'>
9 <table class='table'>
10 <thead>
11 <tr>
12 <th>Title</th>
13 <th>Director</th>
14 <th>Cast</th>
15 <th>Release Date</th>
16 </tr>
17 </thead>
18 <tbody>
19 <tr *ngFor="let movie of movies;">
20 <td>{{movie.title}}</td>
21 <td>{{movie.director}}</td>
22 <td>{{movie.cast}}</td>
23 <td>{{movie.releaseDate}}</td>
24 </tr>
25 </tbody>
26 </table>
27 </div>
28 </div>
29 </div>
30
Source Code
Here is the output

Nested Array
The following example shows how to use the ngFor in a nested array. The employees array has nested skills array.
1
2 employees = [
3 {
4 name: "Rahul", email: "[email protected]",
5 skills: [{ skill: 'Angular', exp: '2' },{ skill: 'Javascript', exp: '7' },{ skill: 'TypeScript', exp: '3' }
6 ]
7 },
8 {
9 name: "Sachin", email: "[email protected]",
10 skills: [{ skill: 'Angular', exp: '1' },{ skill: 'Android', exp: '3' },{ skill: 'React', exp: '2' }
11 ]
12 },
13 {
14 name: "Laxmna", email: "[email protected]",
15 skills: [{ skill: 'HTML', exp: '2' },{ skill: 'CSS', exp: '2' },{ skill: 'Javascript', exp: '1' }
16 ]
17 }
18 ]
19
Source code
Inside the main loop, use the local variable employee to get the list of skills and loop through it using *ngFor="let
skill of employee.skills;"
1
2 <div class='card'>
3 <div class='card-header'>
4 <p>Nested Array</p>
5 </div>
6
7 <div class='table-responsive'>
8 <table class='table table-bordered table-sm '>
9 <thead class="thead-dark">
10 <tr>
11 <th>Name</th>
12 <th>Mail ID</th>
13 <th>Skills</th>
14 </tr>
15 </thead>
16 <tbody>
17 <tr *ngFor="let employee of employees;">
18 <td>{{employee.name}}</td>
19 <td>{{employee.email}}</td>
20 <td>
21 <table class='table table-sm '>
22 <tbody>
23 <tr *ngFor="let skill of employee.skills;">
24 <td>{{skill.skill}}</td>
25 <td>{{skill.exp}}</td>
26 </tr>
27 </tbody>
28 </table>
29
30 </td>
31 </tr>
32 </tbody>
33 </table>
34 </div>
35 </div>
36
Source code

BEST ANGULAR BOOKS


The Top 8 Best Angular Books, which helps you to get started with Angular
Local Variables
ngFor exposes several values, which help us to fine-tune display. We assign these values to the local variable and use
it in our template
The list of exported values provided by ngFor directive
index: number: The zero-based index of the current element in the collection.
count: number: The total no of items in the collection
first: boolean: True when the item is the first item in the collection.
last: boolean: Is set to True, when the item is the last item in the collection.
even: boolean: True when the item has an even index in the collection.
odd: boolean: is set to True when the item has an odd index in the collection.
Finding the Index
To Find the index, we create another local variable i and use the let to make it equal to index.
1
2 let i=index;
3
The following code shows the list of movies along with the index.
1
2 <tr *ngFor="let movie of movies; let i=index;">
3 <td> {{i}} </td>
4 <td>{{movie.title}}</td>
5 <td>{{movie.director}}</td>
6 <td>{{movie.cast}}</td>
7 <td>{{movie.releaseDate}}</td>
8 </tr>
9
Source Code
Formatting odd & even rows
We can use the odd & even values to format the odd & even rows alternatively. To do that create two local
variables o & e. Assign the values of odd & even values to these variables using the let statement. Then use
the ngClass to change the class name to either odd or even. The example code is shown below
1
2 <tr *ngFor="let movie of movies; let i=index; let o= odd; let e=even;"
3 [ngClass]="{ odd: o, even: e }">
4 <td> {{i}} </td>
5 <td>{{movie.title}}</td>
6 <td>{{movie.director}}</td>
7 <td>{{movie.cast}}</td>
8 <td>{{movie.releaseDate}}</td>
9 </tr>
10
Source Code
Add the appropriate background color to the odd and even classes as shown below in app.component.css
1
2 .even { background-color: azure; }
3 .odd { background-color: floralwhite; }
4
Source Code
First and the Last element of a list
Similarly, you can use the first & last values to style the first & last element. The code below will add CSS
classes first & last to the first and last movie using the ngClass.
1
2 <div class='table-responsive'>
3 <table class='table table-bordered table-sm '>
4 <thead class="thead-dark">
5 <tr>
6 <th>Index</th>
7 <th>Title</th>
8 <th>Director</th>
9 <th>Cast</th>
10 <th>Release Date</th>
11 </tr>
12 </thead>
13 <tbody>
14 <tr *ngFor="let movie of movies; let i=index; let first= first; let last=last;" [ngClass]="{ first: first, last: last }">
15 <td> {{i}} </td>
16 <td>{{movie.title}}</td>
17 <td>{{movie.director}}</td>
18 <td>{{movie.cast}}</td>
19 <td>{{movie.releaseDate}}</td>
20 </tr>
21 </tbody>
22 </table>
23 </div>
24
Source Code
Remember to add the CSS classes to app.component.css
1
2 .first { background-color: azure; }
3 .last { background-color: floralwhite; }
4
Source Code
Track By
The angular includes Track By clause, just like AngularJS did. Track By clause allows you to specify your own key to
identify objects.
Angular uses the object identity to compare the elements in the collection to the DOM nodes. Hence when you add
an item or remove an item, the Angular will track it and update only the modified items in the DOM. It does not
render the entire list.
But this fails if we update the list from the backend server. That is because the retrieved objects cannot be compared
with the existing objects in the list as the reference has changed. The Angular simply removes these elements from
DOM and recreates the new elements from the new data. This has a huge performance implication.
Angular trackBy clause eliminates this problem, by telling angular how to identify similar elements. The Angular will
use the value returned by the trackBy function to match the elements returned by the database and update the
DOM Elements without recreating them.
We should always specify the primary key or unique key as the trackBy clause.
Example
In our movie list example, let us make the title of the movie as the identifier.
1
2 <tr *ngFor="let movie of movies; trackBy:trackByFn;">
3 <td>{{movie.title}}</td>
4 <td>{{movie.director}}</td>
5 <td>{{movie.cast}}</td>
6 <td>{{movie.releaseDate}}</td>
7 </tr>
8
Source Code
In the Component Class create a trackByFn. It gets the index and the current item as its argument. It should return
the unique id
1
2 trackByFn(index, item) {
3 return item.title;
4 }
5
Source Code

ngSwitch, ngSwitchcase, ngSwitchDefault Angular Example


5 Comments / 5 minutes of reading / February 20, 2022
ngFor Directive
ngIf Directive

The ngSwitch is an Angular structural directive, which allows us to add or remove DOM elements. It works in
conjunction with ngSwitchcase, & ngSwitchDefault directives. It is similar to the switch statement of JavaScript. In
this tutorial, we will look at the syntax of ngSwitch, ngSwitchcase & ngSwitchDefault. We will show you how to use
these directives using an example. The examples include ngSwitch Example, multiple ngSwitchCase , Loose Equality
Checks, etc.

You can download the source code from GitHub


Table of Contents
Angular ngSwitch Directive
Syntax
ngSwitch
ngSwitchCase
ngSwitchDefault
Important Points
ngSwitch Example
Component Class
Template
More Examples
Component class
Template
Loose Equality Checks
Multiple / Sharing ngSwitchCase
Source Code
References
Angular ngSwitch Directive
The ngSwitch is an Angular directive, which allows us to display one or more DOM elements based on some pre-
defined condition.
The following is the syntax of ngSwitch. It contains three separate
directives. ngSwitch, ngSwitchCase & ngSwitchDefault.
Syntax
1
2 <container_element [ngSwitch]="switch_expression">
3 <inner_element *ngSwitchCase="match_expresson_1">...</inner_element>
4 <inner_element *ngSwitchCase="match_expresson_2">...</inner_element>
5 <inner_element *ngSwitchCase="match_expresson_3">...</inner_element>
6 <inner_element *ngSwitchDefault>...</element>
7 </container_element>
8
ngSwitch
ngSwitch is bound to container_element like div etc. We assign a switch-expression to the ngSwitch via property
binding syntax. Angular evaluates the switch_expression at runtime and based on its value displays or removes the
elements from the DOM.
ngSwitchCase
ngSwitchCase is bound to an inner_element, which we must place inside the container_element. We use * (Asterix
symbol), because it is a structural directive. We also assign a match_expression, which Angular evaluates at runtime.
The Angular displays the inner_element only when the value of the match_expression matches the value of
the switch_expression else it is removed from the DOM.
If there is more than one match, then it displays all of them.
Note that the ngSwitchCase does not hide the element, but removes them from the DOM.
ngSwitchDefault
ngSwitchDefault is also bound to an inner_element, which we must place inside the container_element. But it does
not have any match_expression. If none of the ngSwitchCase match_expression matches the switch_expression,
then the angular displays the element attached to the ngSwitchDefault
You can place ngSwitchDefault anywhere inside the container element and not necessarily at the bottom.
You are free to add more than one ngSwitchDefault directive. Angular displays all of them.
Important Points
You must place ngSwitchCase & ngSwitchDefault inside the ngSwitch directive
Angular displays every element, that matches the switch_expression
If there are no matches, angular displays all the elements, which has ngSwitchDefault directive
You can place one or more than one ngSwitchDefault anywhere inside the container element and not necessarily at
the bottom.
Any element within the ngSwitch statement but outside of any NgSwitchCase or ngSwitchDefault directive is
displayed as it is.
The elements are not hidden but removed from the DOM.
Angular uses loose equality checks to compare the ngSwitchCase expression with the ngSwitch expression. This
means that the empty string "" matches 0.
You can share the template between multiple ngSwitchCase using the ngTemplateOutlet

BEST ANGULAR BOOKS


The Top 8 Best Angular Books, which helps you to get started with Angular
ngSwitch Example
Create a new Angular project. Add the bootstrap CSS to the project by adding the following in the index.html

1 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"


2 integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
3 crossorigin="anonymous">

Component Class
Create a variable num in your Angular Component class
1
2 num: number= 0;
3
Template
1
2 <div class='card'>
3 <div class='card-header'>
4 ngSwitch Example
5 </div>
6 <div class="card-body">
7 Input string : <input type='text' [(ngModel)]="num" />
8
9 <div [ngSwitch]="num">
10 <div *ngSwitchCase="'1'">One</div>
11 <div *ngSwitchCase="'2'">Two</div>
12 <div *ngSwitchCase="'3'">Three</div>
13 <div *ngSwitchCase="'4'">Four</div>
14 <div *ngSwitchCase="'5'">Five</div>
15 <div *ngSwitchDefault>This is Default</div>
16 </div>
17 </div>
18 </div>
19
Now let us examine the code in detail
1
2 Input string : <input type='text' [(ngModel)] ="num"/>
3
We bind the num variable to the input box.
1
2 <div [ngSwitch]="num">
3
We attach the ngSwitch directive to the div element, then bind it to the expression num.
1
2 <div *ngSwitchCase="'1'">One</div>
3
Next, we have a few ngSwitchCase directives attached to the div element with matching expressions “1”,”2” etc.
Whenever the num matches these expressions, the ngSwitchCase displays the element attached to it else it removes
it from DOM.
1
2 <div *ngSwitchDefault>This is Default</div>
3
The ngSwithcDefault does not take any expression, but it is displays only when all other ngSwitchCase match
expressions fail.

More Examples
The following uses the array of objects instead of a variable.
Component class
1
class item {
2
name: string;
3
val: number;
4
}
5
6
export class AppComponent
7
{
8
items: item[] = [{name: 'One', val: 1}, {name: 'Two', val: 2}, {name: 'Three', val: 3}, {name: 'Four', val: 3}, {name:
9
'Five', val: 3}];
10
selectedValue1: string= 'One';
11
selectedValue2: string= 'One';
12
selectedValue3: string= 'One';
13
selectedValue4: string= 'One';
14
}
15
Template
Note that we have two matches for *ngSwitchCase="'Two'". ngSwitchcase renders both.
1
2 <div class='card'>
3 <div class='card-header'>
4 Multiple ngSwitchCase with same condition
5 </div>
6
7 <div class="card-body">
8 <select [(ngModel)]="selectedValue1">
9 <option *ngFor="let item of items;" [value]="item.name">{{item.name}}</option>
10 </select>
11
12 <div [ngSwitch]="selectedValue1">
13 <p *ngSwitchCase="'One'">One is Selected</p>
14 <p *ngSwitchCase="'Two'">Two is Selected</p>
15 <p *ngSwitchCase="'Two'">Two Again used in another element</p>
16 <p *ngSwitchDefault>This is Default</p>
17 </div>
18 </div>
19
20 </div>
21
You can also make use of ng-template directly instead of *ngSwitchCase. In fact *ngSwitchCase="'One'" is a shortcut
to ng-template [ngSwitchCase]="'One'".
1
2 <div class='card'>
3 <div class='card-header'>
4 ngSwitch using ng-template
5 </div>
6
7 <div class="card-body">
8
9 <select [(ngModel)]="selectedValue2">
10 <option *ngFor="let item of items;" [value]="item.name">{{item.name}}</option>
11 </select>
12
13 <div [ngSwitch]="selectedValue2">
14 <ng-template [ngSwitchCase]="'One'">One is Selected</ng-template>
15 <ng-template [ngSwitchCase]="'Two'">Two is Selected</ng-template>
16 <ng-template ngSwitchDefault>This is Default</ng-template>
17 </div>
18
19 </div>
20 </div>
21
More than one ngSwitchDefault. Works perfectly ok.
1
2 <div class='card'>
3 <div class='card-header'>
4 Multiple ngSwitchDefault Directives
5 </div>
6
7 <div class="card-body">
8 <select [(ngModel)]="selectedValue3">
9 <option *ngFor="let item of items;" [value]="item.name">{{item.name}}</option>
10 </select>
11
12
13 <div [ngSwitch]="selectedValue3">
14 <div *ngSwitchCase="'One'">One is Selected</div>
15 <div *ngSwitchDefault>This is Default 1</div>
16 <div *ngSwitchCase="'Two'">Two is Selected</div>
17 <div *ngSwitchDefault>This is Default 2</div>
18 </div>
19
20
21 </div>
22 </div>
23
Loose Equality Checks
Angular uses loose equality checks to compare the ngSwitchCase expression with the ngSwitch expression. This
means that the empty string "" matches 0.
1
2 <div class='card'>
3 <div class='card-header'>
4 loose equality Empty string, "" matches 0
5 </div>
6
7 <div class="card-body">
8
9 Input string : <input type='text' [(ngModel)]="num" />
10
11 <div [ngSwitch]="num">
12 <div *ngSwitchCase="0">Zero is Selected</div>
13 <div *ngSwitchCase="1">One is Selected</div>
14 <div *ngSwitchCase="2">Two is Selected</div>
15 <div *ngSwitchDefault>This is Default 2</div>
16 </div>
17
18
19 </div>
20 </div>
21

Multiple / Sharing ngSwitchCase


You may also want to share the template between two values. For Example One Template for the
values One & Two & another template for values Three & Four. One option is to repeat the template under each
switch case. Or you can also make use of the ngTemplateOutlet to share the template as shown below.
1
2
3 <div class='card'>
4 <div class='card-header'>
5 Sharing Templates
6 </div>
7
8 <div class="card-body">
9
10 <select [(ngModel)]="selectedValue4">
11 <option *ngFor="let item of items;" [value]="item.name">{{item.name}}</option>
12 </select>
13
14
15 <ng-container [ngSwitch]="selectedValue4">
16
17 <ng-container *ngSwitchCase="'One'">
18 <ng-container *ngTemplateOutlet="sharedTemplate12"></ng-container>
19 </ng-container>
20 <ng-container *ngSwitchCase="'Two'">
21 <ng-container *ngTemplateOutlet="sharedTemplate12"></ng-container>
22 </ng-container>
23
24 <ng-container *ngSwitchCase="'Three'">
25 <ng-container *ngTemplateOutlet="sharedTemplate34"></ng-container>
26 </ng-container>
27
28 <ng-container *ngSwitchCase="'Four'">
29 <ng-container *ngTemplateOutlet="sharedTemplate34"></ng-container>
30 </ng-container>
31
32 <ng-template #sharedTemplate12>Shared between 1,2</ng-template>
33 <ng-template #sharedTemplate34>Shared between 3,4</ng-template>
34 <ng-container *ngSwitchDefault>Default Template</ng-container>
35
36 </ng-container>
37
38 </div>
39 </div>
40
Ng-Content & Content Projection in Angular
7 Comments / 7 minutes of reading / October 7, 2020
CanLoad Guard
Input,Output & EventEmitter

In this guide let us explore how to use ng-content to add external content (content projection) in the Template. We
know how to use @Input decorator to pass data from the parent component to the child component. But it is only
limited to data. We cannot use that technique to pass the content which includes the HTML elements, CSS, etc to the
child component. To do that we have to make use of content projection.

Content projection is a way to pass the HTML content from the parent component to the child component. The child
component will display the template in a designated spot. We use the ng-content element to designate a spot in the
template of the child component. The ng-content also allows us to create multiple slots using the selector attribute.
The parent can send different content to each slot.
Table of Contents
What is ng-content
Without ng-content
ng-content Example
Events
Custom Events
Multiple Projections using ng-content
Example of ng-content select attribute
Select attribute is a CSS selector
ng-content without selector catches all
ngProjectAs
References
Summary
What is ng-content
The ng-content tag acts as a placeholder for inserting external or dynamic content. The Parent component passes
the external content to the child component. When Angular parses the template, it inserts the external content
where ng-content appears in the child component’s template
We can use content projection to create a reusable component. The components that have similar logic & layout and
can be used in many places in the application.
Take an example of a card component. It has a header section, footer section & body section. The contents of these
sections will vary. The ng-content will allow us to pass these sections to the card component from the parent
component. This enables us to use the card component at many places in the app.
Without ng-content
To understand how content projection using ng-content works, first let us build a simple button component
without ng-content.
Create a new Angular application. Add a new component btn.component.ts.It is a simple component, which displays
a button with the caption Click Me
1
2 import { Component } from '@angular/core';
3
4 @Component({
5 selector: 'app-btn',
6 template: `<button>
7 Click Me
8 </button>`
9 })
10 export class BtnComponent {
11 }
12
Now go to the app.component.html.
1
2 <h2>Simple Button Demo</h2>
3 <app-btn></app-btn>
4 <app-btn></app-btn>
5
In the code above, we have two buttons with the caption Click Me show up on the screen as expected.
What if we want to change the caption from the parent. We can do that using the @Input property. But
using @input, we can only set the caption of the button. But we cannot change the look and appearance of the
caption.
ng-content Example
Create a new component FancyBtnComponent. Copy all the codes from BtnComponent except for one change.
Remove Click Me and add <ng-content> </ng-content> instead. This tag acts as a placeholder. You can also think of it
as an argument to the component. The parent component must supply the argument
1
2 import { Component, Output, EventEmitter } from '@angular/core';
3
4 @Component({
5 selector: 'app-fancybtn',
6 template: `
7 <button>
8 <ng-content></ng-content>
9 </button> `
10 })
11 export class FancyBtnComponent {
12 }
13
Now open the app.component.html
1
2 <h2>Button Demo With ng-content</h2>
3 <app-fancybtn>Click Me</app-fancybtn>
4 <app-fancybtn><b>Submit</b></app-fancybtn>
5
The content between <app-fancybtn> </app-fancybtn> is passed to our FancyBtnComponent. The component
displays it in place of ng-content.
The advantage of such a solution is that you can pass any HTML content.

BEST ANGULAR BOOKS


The Top 8 Best Angular Books, which helps you to get started with Angular

Events
The events like click, input, etc bubble up. Hence can be captured in the parent as shown below
1
2 **app.component.html**
3
4 <h2>Button with click event</h2>
5 <app-fancybtn (click)="btnClicked($event)"><b>Submit</b></app-fancybtn>
6
7
8 ** App.component.ts ***
9
10 btnClicked($event) {
11 console.log($event)
12 alert('button clicked')
13 }
14
But if you have more than one button, then you may have to inspect the $event argument to check, which button
responsible for the event.
Custom Events
You can create custom events using the @output as shown in below
1
2 @Output() someEvent:EventEmitter =new EventEmitter();
3
4 raiseSomeEvent() {
5 this.someEvent.emit(args);
6}
7
In parent component
1
2 <app-fancybtn (someEvent)=”DoSomething($event)”><b>Submit</b></app-fancybtn>
3
Multiple Projections using ng-content
The button example is a very simple example. The ng-content is much more powerful than that. It allows us to create
multiple slots in the template. Each slot must define a selector. You can think this as a multiple arguments to the
component
In the parent component we can create different contents and each of those contents can be projected into any of
those slots depending on their selector. To implement this we make use of the ng-content Select attribute. The
select attribute is a CSS Selector
Example of ng-content select attribute
For Example, create a new component card.component.ts
1
2 import { Component } from '@angular/core';
3
4
5 @Component({
6 selector: 'app-card',
7 template: `
8 <div class="card">
9 <div class="header">
10 <ng-content select="header" ></ng-content>
11 </div>
12 <div class="content">
13 <ng-content select="content" ></ng-content>
14 </div>
15 <div class="footer">
16 <ng-content select="footer" ></ng-content>
17 </div>
18 </div>
19 `,
20 styles: [
21 ` .card { min- width: 280px; margin: 5px; float:left }
22 .header { color: blue}
23 `
24 ]
25 })
26 export class CardComponent {
27 }
28
29
In the above example, we have three ng-content slots, each have a selector header,content & footer
Now open the app.component.html add the following code
1
2 <app-card>
3 <header><h1>Angular</h1></header>
4 <content>One framework. Mobile & desktop.</content>
5 <footer><b>Super-powered by Google </b></footer>
6 </app-card>
7
8 <app-card>
9 <header><h1 style="color:red;">React</h1></header>
10 <content>A JavaScript library for building user interfaces</content>
11 <footer><b>Facebook Open Source </b></footer>
12 </app-card>
13
Select attribute is a CSS selector
You can use any CSS selector as the select attribute. Like class, element, id attributes, etc. For Example, the above
card component using the CSS class
1
2 import { Component } from '@angular/core';
3
4 @Component({
5 selector: 'card',
6 template: `
7 <div class="card">
8 <div class="header">
9 <ng-content select=".header" ></ng-content>
10 </div>
11 <div class="content">
12 <ng-content select=".content" ></ng-content>
13 </div>
14 <div class="footer">
15 <ng-content select=".footer" ></ng-content>
16 </div>
17 </div>
18 `,
19 styles: [
20 ` .card { width: 280px; margin: 5px; float:left; border-width:1px; border-style:solid ; }
21 .header { color: blue}
22 `
23 ]
24 })
25 export class CardComponent {
26
And in the component, we use it as
1
2 <card>
3 <div class="header">
4 <h1>Angular</h1>
5 </div>
6 <div class="content">One framework. Mobile & desktop.</div>
7 <div class="footer"><b>Super-powered by Google </b></div>
8 </card>
9
10 <card>
11 <div class="header">
12 <h1 style="color:red;">React</h1>
13 </div>
14 <div class="content">A JavaScript library for building user interfaces</div>
15 <div class="footer"><b>Facebook Open Source </b></div>
16 </card>
17
Similarly, you can use the various CSS Selectors as shown below
1
2 <ng-content select="custom-element" ></ng-content>
3 <ng-content select=".custom-class" ></ng-content>
4 <ng-content select="[custom-attribute]" ></ng-content>
5
ng-content without selector catches all
Now, in the following example, the last paragraph does not belong to any ng-content slots. Hence ng-content will
not project the last para as it cannot determine where to add.
1
2 <card>
3 <div class="header"><h1>Typescript</h1></div>
4 <div class="content">Typescript is a javascript for any scale</div>
5 <div class="footer"><b>Microsoft </b></div>
6 <p>This text will not be shown</p>
7 </card>
8
To solve the above issue, we can include ng-content without any selector. It will display all the content, which cannot
be projected into any other slots.
1
2 import { Component } from '@angular/core';
3
4
5 @Component({
6 selector: 'app-card',
7 template: `
8 <div class="card">
9 <div class="header">
10 <ng-content select="header" ></ng-content>
11 </div>
12 <div class="content">
13 <ng-content select="content" ></ng-content>
14 </div>
15 <div class="footer">
16 <ng-content select="footer" ></ng-content>
17 </div>
18 <ng-content></ng-content>
19 </div>
20 `,
21 styles: [
22 ` .card { min- width: 280px; margin: 5px; float:left }
23 .header { color: blue}
24 `
25 ]
26 })
27 export class CardComponent {
28 }
29
ngProjectAs
Sometimes it becomes necessary to wrap the component using the ng-container. Most of the time when you use a
structural directive like ngIf or ngSwitch.
In the following example, we enclosed the header inside the ng-container.
1
2 <card>
3 <ng-container>
4 <div class="header">
5 <h1 style="color:red;">React</h1>
6 </div>
7 </ng-container>
8 <div class="content">A JavaScript library for building user interfaces</div>
9 <div class="footer"><b>Facebook Open Source </b></div>
10 </card>
11
12
Because of the ng-container, the header section is not projected to the header slot. Instead, it is projected to the ng-
content slot which does not have a selector set.
To help in such a scenario, you can make use of ngProjectAs attribute as shown below.
1
2 <card>
3 <ng-container ngProjectAs="header">
4 <div>
5 <h1 style="color:red;">React</h1>
6 </div>
7 </ng-container>
8 <div class="content">A JavaScript library for building user interfaces</div>
9 <div class="footer"><b>Facebook Open Source </b></div>
10 </card>
11
References
Source Code
Responding to projected content changes
ng-content the hidden docs
ng-container
@Input, @Output & EventEmitter
ngIf
ngSwitch
ngFor
Child/Nested Components in Angular
Angular @input, @output & EventEmitter
14 Comments / 7 minutes of reading / May 16, 2021
ng-content & Content Projection
Template Reference Variable

In this guide let us learn how to make use of @input, @output & EventEmitter in Angular. We use these decorators
to pass data from parent to child component & vice versa. @Input defines the input property in the component,
which the parent component can set. The @output defines the output property (event), which we raise in the child
component using the EventEmitter. The parent listens to these events.

Table of Contents
@input, @output & Eventemitter
@input
@output
EventEmitter
@input, @output & Eventemitter Example
Child Component
Parent Component
Notes on @Input & @Output
You can also pass the optional name
Intercept input property changes with a setter
Subscribe to @Input changes using ngChanges
EventEmitters are observable
Pass by reference
References
Summary
@input, @output & Eventemitter
@input
Input decorator marks the property as the input property. I.e it can receive data from the parent component. The
parent component uses the property binding to bind it to a component property. Whenever the value in the parent
component changes angular updates the value in the child component.
Example
Consider the following component class
1
2 @Component({
3 selector: 'app-customer-detail',
4 templateUrl: './customer-detail.component.html',
5 styleUrls: ['./customer-detail.component.css']
6 })
7 export class CustomerDetailComponent implements OnInit {
8 @Input() customer:Customer;
9 }
10
We have Input decorator on the customer property. The component expects that the parent component will supply
its value.
The parent component supplies the customer object using the property binding syntax. We add a square bracket
around the customer property. Assign template expression (selectedCustomer) to it, which is a property in the
parent component.
1
2 <app-customer-detail [customer]="selectedCustomer"></app-customer-detail>
3
@output
Output decorates the property as the output property. We initialize it as an EventEmitter. The child component
raises the event and passes the data as the argument to the event. The parent component listens to events
using event binding and reads the data.
Example
1
2 //Declare the property
3 @Output() customerChange:EventEmitter<Customer> =new EventEmitter<Customer>();
4
5 //Raise the event to send the data back to parent
6 update() {
7 this.customerChange.emit(this.customer);
8}
9
The customerChange is the Output property and is of type EventEmitter.
In the parent component, we subscribe to the event using the event binding syntax. Use the () around the event
name (customerChange) and assign a template statement (update($event)) to it. It receives the data in
the $event argument.
1
<app-customer-detail [customer]="selectedCustomer" (customerChange)="update($event)"></app-customer-
2
detail>
3
Remember you must use the argument name as $event.
EventEmitter
EventEmitter is responsible for raising the event. The @output property normally is of type EventEmitter. The child
component will use the emit() method to emit an event along with the data.
1
2 //Define output property
3 @Output() customerChange:EventEmitter<Customer> =new EventEmitter<Customer>();
4
5 //Raise the event using the emit method.
6 update() {
7 this.customerChange.emit(this.customer);
8}
9
Now let us build an app to learn how to use Input, output & EventEmitter

BEST ANGULAR BOOKS


The Top 8 Best Angular Books, which helps you to get started with Angular
@input, @output & Eventemitter Example
The app we build has two components. The parent component shows a list of customers. The user has the option to
click on the edit button, which results in a child component displaying the customer form Once the user updates the
records, the child component raises the event. The parent captures the event. The parent then updates the list with
the new data.
Create a new application using the following command
1
2 ng new InputOutputExample
3
4
5 cd InputOutputExample
6
Create the customerList & customerDetail components. Also, create the customer class
1
2 ng g c customerList
3 ng g c customerDetail
4 ng g class customer
5
Customer
1
2 export class Customer {
3
4 customerNo: number=0;
5 name: string="";
6 address: string="";
7 city: string="";
8 state: string="";
9 country: string="";
10
11 }
12
app.module.ts
The ngModel needs the FormsModule. Hence import it and add it in import metadata.
1
2 import { BrowserModule } from '@angular/platform-browser';
3 import { NgModule } from '@angular/core';
4 import { FormsModule } from '@angular/forms'
5
6 import { AppRoutingModule } from './app-routing.module';
7 import { AppComponent } from './app.component';
8 import { CustomerListComponent } from './customer-list/customer-list.component';
9 import { CustomerDetailComponent } from './customer-detail/customer-detail.component';
10
11 @NgModule({
12 declarations: [
13 AppComponent,
14 CustomerListComponent,
15 CustomerDetailComponent
16 ],
17 imports: [
18 BrowserModule,
19 AppRoutingModule,
20 FormsModule
21 ],
22 providers: [],
23 bootstrap: [AppComponent],
24 })
25 export class AppModule { }
26
27
Child Component
The child component gets an instance of the customer in its input property customer. The parent needs to set it
using the property binding
Users can edit the customer. Once finished they will click the update button. The update method raises
the customerChange event. We pass the customer as the argument to the event. The parent component listens to
the event and receives the data.
The following is the complete code of the CustomerDetailComponent.
1
2 import { Component, OnInit, Input, Output,EventEmitter } from '@angular/core';
3 import { Customer } from '../customer';
4
5 @Component({
6 selector: 'app-customer-detail',
7 templateUrl: './customer-detail.component.html',
8 styleUrls: ['./customer-detail.component.css']
9 })
10 export class CustomerDetailComponent implements OnInit {
11
12 @Input() customer:Customer = new Customer();
13 @Output() customerChange:EventEmitter<Customer> =new EventEmitter<Customer>();
14
15 constructor() { }
16
17 ngOnInit() {
18 }
19
20 update() {
21 this.customerChange.emit(this.customer);
22 }
23
24 }
25
'app-customer-detail' is the name of the selector for this component.
The customer property is the input property decorated with Input.
1
2 @Input() customer:Customer = new Customer();
3
customerChange is decorated as the output property of type EventEmitter
1
2 @Output() customerChange:EventEmitter<Customer> =new EventEmitter<Customer>();
3
Whenever the user updates the customer, we raise the event customerChange. We pass the updated customer as
the argument to it.
1
2 update() {
3 this.customerChange.emit(this.customer);
4}
5
The customer-detail.component.htmlis as follows.
1
2 <p>Customer No : {{customer.customerNo}}</p>
3 <p>Name : <input [(ngModel)]="customer.name"></p>
4 <p>Address : <input [(ngModel)]="customer.address"></p>
5 <p>city : <input [(ngModel)]="customer.city"></p>
6 <p>state : <input [(ngModel)]="customer.state"></p>
7 <p>country : <input [(ngModel)]="customer.country"></p>
8
9 <button (click)="update()">Update</button>
10
The ngModel binds the customer to the input element. It is a two-way binding. The click event of the button is bound
to update() method in the component.
Parent Component
The job of the parent component is to display a list of customers. When the user clicks on the edit button pass the
selected customer to the child component. Then wait for the customerChange event. Update the customer’s list on
receipt of data from the child.
The following is the customer-list.component.html
1
<h2>List of Customers</h2>
2
3
<table class='table'>
4
<thead>
5
<tr>
6
<th>No</th>
7
<th>Name</th>
8
<th>Address</th>
9
<th>City</th>
10
<th>State</th>
11
<th>Country</th>
12
<th>Edit</th>
13
</tr>
14
</thead>
15
<tbody>
16
<tr *ngFor="let customer of customers;">
17
<td>{{customer.customerNo}}</td>
18
<td>{{customer.name}}</td>
19
<td>{{customer.address}}</td>
20
<td>{{customer.city}}</td>
21
<td>{{customer.state}}</td>
22
<td>{{customer.country}}</td>
23
<td><button (click)="showDetails(customer)">Edit</button></td>
24
</tr>
25
</tbody>
26
</table>
27
28
<h3>Details</h3>
29
<app-customer-detail [customer]="selectedCustomer" (customerChange)="update($event)"></app-customer-
30
detail>
31
Use the ngFor directive to loop through the customer list and display the customer details.
1
2 <tr *ngFor="let customer of customers;">
3
The event binding to capture the click event. We pass the customer object to the showDetails method
1
2 <td><button (click)="showDetails(customer)">Edit</button></td>
3
app-customer-detail is the selector for the CustomerDetailComponent. We use the property binding to send
the selectedCustomer to the child component. The child component raises the customerChange event, which we
listen to using the event binding and call the update method.
Customer-list.component.ts
The component code of the parent component. It has two method showDetails & update
1
2 import { Component, OnInit } from '@angular/core';
3 import { Customer } from '../customer';
4 import { element } from 'protractor';
5 import { ObjectUnsubscribedError } from 'rxjs';
6
7 @Component({
8 selector: 'app-customer-list',
9 templateUrl: './customer-list.component.html',
10 styleUrls: ['./customer-list.component.css']
11 })
12 export class CustomerListComponent implements OnInit {
13
14 customers: Customer[] = [
15
16 {customerNo: 1, name: 'Rahuld Dravid', address: '', city: 'Banglaore', state: 'Karnataka', country: 'India'},
17 {customerNo: 2, name: 'Sachin Tendulkar', address: '', city: 'Mumbai', state: 'Maharastra', country: 'India'},
18 {customerNo: 3, name: 'Saurrav Ganguly', address: '', city: 'Kolkata', state: 'West Bengal', country: 'India'},
19 {customerNo: 4, name: 'Mahendra Singh Dhoni', address: '', city: 'Ranchi', state: 'Bihar', country: 'India'},
20 {customerNo: 5, name: 'Virat Kohli', address: '', city: 'Delhi', state: 'Delhi', country: 'India'},
21
22 ]
23
24 selectedCustomer:Customer = new Customer();
25
26 constructor() { }
27
28 ngOnInit() {
29 }
30
31 showDetails(customer:Customer) {
32 this.selectedCustomer=Object.assign({},customer)
33 }
34
35 update(customer:Customer) {
36 console.log(customer)
37 var cust=this.customers.find(e => e.customerNo==customer.customerNo)
38 Object.assign(cust,customer)
39 alert("Customer Saved")
40 }
41 }
42
The showDetails method gets the customer as its argument. We clone it & assign it to selectedCustomer
Since the customer is an object it is Passed by Reference. When you make any modification to the customer it will
also be reflected in the customer’s collection. We want the update the customer’s only when we get the data from
the child. Hence we clone the customer and send it to the child component.
If you are passing primitive data types like numbers are Passed by Value.
Finally in the root component (i.e. app.component.html ) copy the following
1
2 <app-customer-list></app-customer-list>
3
Run the app

Notes on @Input & @Output


You can also pass the optional name
Input decorator allows us to pass an option name, which you can use it while binding in the parent
For Example
1
2 @Input(‘customerData’) customer:Customer;
3
Intercept input property changes with a setter
You can also create a setter property
1
2 private _customerData = '';
3 @Input()
4 set customer(customer: Customer) {
5 //You can add some custom logic here
6 this._customerData = customer;
7 console.log(this._customerData)
8 }
9 get customer(): string { return this._customerData; }
10
Subscribe to @Input changes using ngChanges
You can also subscribe to the changes using ngOnChanges life cycle hook.
EventEmitters are observable
EventEmitters are RxJs Subjects. Hence you can make use of RxJs operators to manipulate them. Read more about it
from this link.
Pass by reference
The objects are passed by reference. Hence if you modify the object, you are updating the original object. The
primitive data types like numbers are Passed by Value.
different slots using the selector attribute. These slots allow us to add different content to different slots
Template Reference Variable in Angular
2 Comments / 5 minutes of reading / May 16, 2021
Input, Output & EventEmitter
ng-container

This guide explains the Template Reference Variable in Angular. We find out what template reference variable is.
How to define and use it in Angular.

Table of Contents
Template Reference Variable
Defining Template Reference variable
Template Reference variable Example
HTML Element
Pass Variable to Component class
Component/Directive
ExportAs
The safe navigation operator ( ? )
Template Driven Forms
Template Input Variable
Variable Scope
Child scope
References
Summary
Template Reference Variable
The Template reference variable is a reference to any DOM element, component or a directive in the Template. We
can use it elsewhere in the template. We can also pass it to a method in the component. It can contain a reference
to elements like h1, div, etc
Defining Template Reference variable
We declare Template reference variables using # followed by the name of the variable ( #variable). We can also
declare them using #variable="customer" when the component/directive defines a customer as
the exportAs Property.
For Example
HTML Element
1
2 <input type="text" #firstName>
3
Component/Directive
1
2 <app-customer #customerList=”customer”></app-customer>
3
Component/Directive with exportAs
1
2 <app-customer #customerList=”customer”></app-customer>
3
Template Reference variable Example
Now let us create a simple sample application to learn how to use a template reference variable
Create a new application
1
2 ng new templateVariable
3
HTML Element
The following Example code defines the #firstName & #lastName template reference variables. They both contain
the reference to the input HTML Element.
The input elements contain the value property. Hence we can use it to display the welcome message as shown
below.
app.component.html
1
2 <h1>{{title}}</h1>
3
4 <p>
5 <label for="firstName">First Name</label>
6 <input (keyup)="0" type="text" #firstName id="firstName">
7 </p>
8
9 <p>
10 <label for="lastName">Last Name</label>
11 <input (keyup)="0" type="text" #lastName id="lastName">
12 </p>
13
14 <b>Welcome {{firstName.value}} {{lastName.value}} </b>
15
We have used (keyup)="0" on the input element. It does nothing but it forces the angular to run the change
detection. change detection, in turn, updates the view.
The Angular updates the view, when it runs the change detection. The change detection runs only in response to
asynchronous events, such as the arrival of HTTP responses, raising of events, etc. In the example above whenever
you type on the input box, it raises the keyup event. It forces the angular to run the change detection, hence the
view gets the latest values.
Pass Variable to Component class
You can also pass the variables to the component as shown below. Add this code app.component.html
1
2 <p>
3 <button (click)="sayHello(firstName, lastName)"> Say Hello</button>
4 </p>
5
6
Add this to app.component.ts
1
2 sayHello(firstName, lastName) {
3 alert('Hello '+firstName.value+' '+ lastName.value)
4}
5

BEST ANGULAR BOOKS


The Top 8 Best Angular Books, which helps you to get started with Angular
Component/Directive
You can get a reference to the component or directive. Refer to the tutorial on How to create child/nested
component in Angular
Create a new component customer-list.component.ts
1
2 import { Component } from '@angular/core';
3 import { Customer } from './customer';
4
5 @Component({
6 selector: 'app-customer-list',
7 templateUrl: './customer-list.component.html',
8 exportAs:'customerList'
9 })
10 export class CustomerListComponent {
11
12 selectedCustomer
13
14 customers: Customer[] = [
15
16 {customerNo: 1, name: 'Rahuld Dravid', address: '', city: 'Banglaore', state: 'Karnataka', country: 'India'},
17 {customerNo: 2, name: 'Sachin Tendulkar', address: '', city: 'Mumbai', state: 'Maharastra', country: 'India'},
18 {customerNo: 3, name: 'Saurrav Ganguly', address: '', city: 'Kolkata', state: 'West Bengal', country: 'India'},
19 {customerNo: 4, name: 'Mahendra Singh Dhoni', address: '', city: 'Ranchi', state: 'Bihar', country: 'India'},
20 {customerNo: 5, name: 'Virat Kohli', address: '', city: 'Delhi', state: 'Delhi', country: 'India'},
21
22 ]
23 }
24
customer-list.component.html
1
2 <h2>List of Customers</h2>
3
4 <table class='table'>
5 <thead>
6 <tr>
7 <th>No</th>
8 <th>Name</th>
9 <th>Address</th>
10 <th>City</th>
11 <th>State</th>
12 <th>Select</th>
13 </tr>
14 </thead>
15 <tbody>
16 <tr *ngFor="let customer of customers;">
17 <td>{{customer.customerNo}}</td>
18 <td>{{customer.name}}</td>
19 <td>{{customer.address}}</td>
20 <td>{{customer.city}}</td>
21 <td>{{customer.state}}</td>
22 <button (click)="selectedCustomer=customer">Select</button>
23 </tr>
24 </tbody>
25 </table>
26
customer.ts
1
2 export class Customer {
3
4 customerNo: number;
5 name:string ;
6 address:string;
7 city:string;
8 state:string;
9 country:string;
10
11 }
12
app.component.html
1
2 You have selected {{customerListComponent.selectedCustomer?.name}}
3 <app-customer-list #customerListComponent></app-customer-list>
4
ExportAs
Sometimes there could be more than one directive on a DOM Element.
For Example in the following code has two directives. In such a case, we need to specify which directive to use
for #variable.
1
2 <a-directive b-directive #variable />
3
The components or directives can use exportAs to export the component/directive in a different name.
For Example, open the customer-list.component and add the exportAs:'customerList' under
the @Component metadata
1
2 @Component({
3 selector: 'app-customer-list',
4 templateUrl: './customer-list.component.html',
5 exportAs:'customerList'
6 })
7
8
Now you can use it a
1
2 You have selected {{customerList.selectedCustomer?.name}}
3 <app-customer-list #customerList="customerList"></app-customer-list>
4
The safe navigation operator ( ? )
The selectedCustomer is null when the app starts for the first time. It gets its value only when the user clicks on the
select button. Hence we use ? or a safe navigation operator to guard against null or undefined value.
Without ? the app will throw error and stops
Template Driven Forms
The ngForm directive uses the exportAs to export an instance of itself using the name ngForm. We use this in
the template-driven forms in Angular.
1
2 <form #contactForm="ngForm" (ngSubmit)="onSubmit(contactForm)">
3
Now, you can check value and validate the status of the form within the template
1
2 <pre>Value : {{contactForm.value | json }} </pre>
3 <pre>Valid : {{contactForm.valid}} </pre>
4 <pre>Touched : {{contactForm.touched }} </pre>
5 <pre>Submitted : {{contactForm.submitted }} </pre>
6
Template Input Variable
The Template reference variable must not be confused with the Template input variable, which we define using the
let keyword in the template.
For Example, check the ngFor loop in the customer-list.component.html. The variable customer is a template input
variable
1
2 <tr *ngFor="let customer of customers;">
3 <td>{{customer.customerNo}}</td>
4 <td>{{customer.name}}</td>
5 <td>{{customer.address}}</td>
6 <td>{{customer.city}}</td>
7 <td>{{customer.state}}</td>
8 <button (click)="selectedCustomer=customer">Select</button>
9 </tr>
10
11
Variable Scope
The scope of the template reference variable is the template within which it is declared. You cannot access it outside
the template.
Hence any variable declared in CustomerListComponent cannot be accessed from the app component although we
render the customer list within the app component.
Child scope
Also, note that we can create a new child template scope (nested scope) by using the directive ng-template . Also
the structural directive like ngIf, ngFor, etc also creates their own child scope.
The following is an example of the <ng-template> directive. The address variable defined inside the ng-template is
not accessible outside it.
1
2 <h2>Variable Scope</h2>
3
4 <div *ngIf="false else addressTemplate"></div>
5
6 <ng-template #addressTemplate>
7 <p>
8 <label for="address">Address</label>
9 <input (keyup)="0" type="text" #address id="address">
10 </p>
11 <p>The address of {{firstName.value}} {{lastName.value}} Entered {{address.value}} </p>
12
13 </ng-template>
14
15 <!-- address is not accessible here -->
16 <p>
17 You Entered {{address?.value}}
18 </p>
19
20
ngIf Example
1
2 <div *ngIf="true">
3 <app-customer-list #variable></app-customer-list
4 //variable is accessible from here
5 </div>
6
7 //variable is not accessible from here
8
9
References
Angular Docs
Template Driven Forms
Summary
The Template reference variable is a reference to any DOM element, component or a directive in the Template.
Use #variable to create a reference to it. We can also use #variable=”exportAsName” when the component/directive
defines an exportAs metadata. The template variable can be used anywhere in the template. The variable can be
passed the component as an argument to a method. The Template reference variable is different from the template
input variable which we define using the let keyword within the template. They are Template scoped. Also, make use
of the safe navigation operator ?, if you expect a null value.

Angular Observable Tutorial


10 Comments / 9 minutes of reading / August 20, 2021
Angular Decorators
Create Observable from a string, array. object, collection

The Angular Observable tutorial covers what is observable in Angular 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, Observable, Observers, RxJS, etc. It is very important to understand these terms before we start using
the observables
Rx stands from Reactive programming. It is defined as programming with asynchronous data streams. So it is
important that you understand what is data stream is.
Table of Contents
What is a data stream
Reactive Programming
What is RxJS
What is an Observable in Angular
Who are observers (subscribers)
Angular Observable tutorial
Import the required libraries
Observable Creation
Subscribing to the observable
Adding interval
Error event
Complete Event
Observable Operators
Unsubscribing from an Observable
References
Summary
What is a data stream
A stream is a data, which arrives over a period of 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 & y positions of mouse click events. Assume that user has clicked on the
locations (12,15), (10,12), (15,20) & (17,15) in that order.
The following diagram shows how the values arrive over a period of time. As you can see stream emits the values as
they happen i.e asynchronously.

mouse
click events as data streams

BEST ANGULAR BOOKS


The Top 8 Best Angular Books, which helps you to get started with Angular
Value is not the only thing that stream emits. The stream may complete as the user closes the window or app. Or an
error may happen which results in the closure of the stream. At any point in time stream may emit any of 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 the three possibilities in a stream

mouse click events as data streams with emit


error and complete events
As said earlier the stream of data can be anything. For Example
Mouse click or Mouse hover events with x & y positions
Keyboard events like keyup, keydown, keypress, etc
Form events like value changes etc
Data which arrives after an HTTP request
User Notifications
Measurements from any sensor
Important Points regarding streams can
emit zero, one or more values of any time.
can also emit errors.
must emit the complete signal, when completes (finite streams).
can be infinite, that they never complete
Now, we have understood what is a data stream, let us look at what is Reactive Programming is
Reactive Programming
The reactive programming is all about creating the stream, emitting value, error or complete signals, manipulate,
transfer or do something useful with the data streams.
This is where the RxJs comes 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
The Angular uses the RxJS library heavily in its framework to implement Reactive Programming. Some of the
examples where reactive programming used are
Reacting to an HTTP request in Angular
Value changes / Status Changes in Angular Forms
The Router and Forms modules use observables to listen for and respond to user-input events.
You can define custom events that send observable output data from a child to a parent component.
The HTTP module uses observables to handle AJAX requests and responses.
The RxJs has two main players
Observable
Observers ( Subscribers)
What is an Observable in Angular
Observable is a function that converts the ordinary stream of data into an observable stream of data. You can think
of Observable as a wrapper around the ordinary stream of data.
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 observers (subscribers)
The Observable on its own is useless unless 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 with the observable to receive the value from the observable. While subscribing it
optionally passes the three callbacks. next(), error() & complete()
Angular Observable Tutorial how
observable and observers communicates with callbacks
The observable starts emitting 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.
Observers/subscribers subscribe to Observables
Observer registers three callbacks with the observable at the time of subscribing. i .e next(), error() & complete()
All three callbacks are optional
The observer receives the data from the observer via the next() callback
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
1
2 import { Observable } from 'rxjs';
3
Observable Creation
There are few ways in which you can create observable in angular. Simplest is to use the Observable constructor. The
observable constructor takes 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
1
2 obs = new Observable((observer) => {
3 console.log("Observable starts")
4 observer.next("1")
5 observer.next("2")
6 observer.next("3")
7 observer.next("4")
8 observer.next("5")
9 })
10
Source Code
The variable obs is now of the type of observable.
The above example declares the obs as the observable but does not instantiate it. To make the observable to emit
values, we need to subscribe to it.
Creating
observable in Angular Observable Tutorial app
In the above example, we used the Observable Constructor to create the Observable. There are many operators
available with the RxJS library, which makes the task of creating the observable easy. These operators help us to
create observable from an array, string, promise, any iterable, etc. Here are list 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 can optionally, include the three
callbacks next(), error() & complete() as shown below
1
2 ngOnInit() {
3
4 this.obs.subscribe(
5 val => { console.log(val) }, //next callback
6 error => { console.log("error") }, //error callback
7 () => { console.log("Completed") } //complete callback
8 )
9 }
10
The complete app.component.ts code is as shown below.
1
2 import { Component, OnInit } from '@angular/core';
3 import { Observable } from 'rxjs';
4
5 @Component({
6 selector: 'app-root',
7 templateUrl: './app.component.html',
8 styleUrls: ['./app.component.css']
9 })
10 export class AppComponent implements OnInit {
11 title = 'Angular Observable using RxJs - Getting Started';
12
13 obs = new Observable((observer) => {
14 console.log("Observable starts")
15 observer.next("1")
16 observer.next("2")
17 observer.next("3")
18 observer.next("4")
19 observer.next("5")
20 })
21
22 data=[];
23
24 ngOnInit() {
25
26 this.obs.subscribe(
27 val=> { console.log(val) },
28 error => { console.log("error")},
29 () => {console.log("Completed")}
30 )
31 }
32 }
33
Source Code
Now, run the code and watch the debug window.
Adding interval
We can add a timeout to insert a delay in each next() callback
1
2 obs = new Observable((observer) => {
3 console.log("Observable starts")
4
5 setTimeout(() => { observer.next("1") }, 1000);
6 setTimeout(() => { observer.next("2") }, 2000);
7 setTimeout(() => { observer.next("3") }, 3000);
8 setTimeout(() => { observer.next("4") }, 4000);
9 setTimeout(() => { observer.next("5") }, 5000);
10
11 })
12
Source Code
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 values 4 & 5 are never emitted.
1
2 obs = new Observable((observer) => {
3 console.log("Observable starts")
4
5 setTimeout(() => { observer.next("1") }, 1000);
6 setTimeout(() => { observer.next("2") }, 2000);
7 setTimeout(() => { observer.next("3") }, 3000);
8 setTimeout(() => { observer.error("error emitted") }, 3500); //sending error event. observable stops here
9 setTimeout(() => { observer.next("4") }, 4000); //this code is never called
10 setTimeout(() => { observer.next("5") }, 5000);
11
12 })
13
Source Code
You can send the error object as the argument to the error method
Observable with the error event
Complete Event
Similarly the complete event. The observables stop after emitting the complete signal. Hence values 4 & 5 are never
emitted.
1
2 obs = new Observable((observer) => {
3 console.log("Observable starts")
4
5 setTimeout(() => { observer.next("1") }, 1000);
6 setTimeout(() => { observer.next("2") }, 2000);
7 setTimeout(() => { observer.next("3") }, 3000);
8 setTimeout(() => { observer.complete() }, 3500); //sending complete event. observable stops here
9 setTimeout(() => { observer.next("4") }, 4000); //this code is never called
10 setTimeout(() => { observer.next("5") }, 5000);
11
12 })
13
Source Code
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].
1
2 obs.pipe(
3 obs = new Observable((observer) => {
4 observer.next(1)
5 observer.next(2)
6 observer.next(3)
7 observer.next(4)
8 observer.next(5)
9 observer.complete()
10 }).pipe(
11 filter(data => data > 2), //filter Operator
12 map((val) => {return val as number * 2}), //map operator
13 )
14
The following table lists some of the commonly used operators
AREA OPERATORS

Combination combineLatest, concat, merge, startWith , withLatestFrom, zip


AREA OPERATORS

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 need to 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
1
2 obs: Subscription;
3
Assign the subscription to the obs variable
1
2
3 this.obs = this.src.subscribe(value => {
4 console.log("Received " + this.id);
5 });
6
7
Call the unsubscribe() method in the ngOnDestroy method.
1
2 ngOnDestroy() {
3 this.obs.unsubscribe();
4}
5
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 emits the
complete signal, close the observable.
To learn more about it refer to the tutorial Unsubscribing from an Observable in Angular.
References
observables
RX-library
observables in angular
Practical observable usage
Comparing observables
Observable Design Pattern
Summary
Reactive programming is about programming the stream. The RxJS library brings Reactive Programming into Angular.
Using RxJs, we can create an observable, which can emit 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
Read More
Angular Tutorial
Angular Observable Tutorial
Create Observable from a string, array. object, collection
Observable from events using fromEvent
Observable pipe
Map Operator
Filter Operator
Tap Operator
SwitchMap
MergeMap
ConcatMap
ExhaustMap
take, takeUntil, takeWhile, takeLast
First, last & Single
Skip, SkipWhile, SkipUntil & SkipLast
Scan & Reduce
DebounceTime & Debounce
Delay & DelayWhen
ThrowError
CatchError
ReTry & ReTryWhen
Unsubscribe from an observable
Subjects in Angular
ReplaySubject, BehaviorSubject & AsyncSubject
Angular Subject Example
Create observable from a string, array & object in angular
4 Comments / 5 minutes of reading / June 14, 2020
Angular Observable Tutorial
Observable from Event

In this tutorial, we will show you how to create observable using create, of, from operators in Angular. We can use
them to create new observable from the array, string, object, collection or any static data. Also learn the difference
between the Of & From operators. If you are new to observable, we recommend you to read the Angular
observable before continuing here.

Table of Contents
Observable creation functions
Create
Observable Constructor
Of Operator
observable from an array
observable from a sequence of numbers
observable from string
observable from a value, array & string
From Operator
observable from an array
Observable from string
Observable from collection
Observable from iterable
Observable from promise
Of Vs From
References
Summary
Observable creation functions
There are many ways to create observable in Angular. You can make use of Observable Constructor as shown in
the observable tutorial. There are a number of functions that are available which you can use to create new
observables. These operators help us to create observable from an array, string, promise, any iterable, etc. Here are
some of the operators
create
defer
empty
from
fromEvent
interval
of
range
throw
timer
All the creation related operators are part of the RxJs core library. You can import it from the ‘rxjs’ library
Create
The Create method is one of the easiest. The create method calls the observable constructor behind the scene.
Create is a method of the observable object, Hence you do not have to import it.
1
2 ngOnInit() {
3
4 //Observable from Create Method
5 const obsUsingCreate = Observable.create( observer => {
6 observer.next( '1' )
7 observer.next( '2' )
8 observer.next( '3' )
9
10 observer.complete()
11 })
12
13 obsUsingCreate
14 .subscribe(val => console.log(val),
15 error=> console.log("error"),
16 () => console.log("complete"))
17 }
18
19
20
21 ****Output *****
22 1
23 2
24 3
25 Complete
26

BEST ANGULAR BOOKS


The Top 8 Best Angular Books, which helps you to get started with Angular
Observable Constructor
We looked at this in the previous tutorial. There is no difference between the Observable.create method and
observable constructor. The Create method calls the constructor behind the scene.
1
2 ngOnInit() {
3 //Observable Using Constructor
4 const obsUsingConstructor = new Observable( observer => {
5 observer.next( '1' )
6 observer.next( '2' )
7 observer.next( '3' )
8
9 observer.complete()
10 })
11
12 obsUsingConstructor
13 .subscribe(val => console.log(val),
14 error=> console.log("error"),
15 () => console.log("complete"))
16 }
17
18
19 ****Output *****
20 1
21 2
22 3
23 complete
24
Of Operator
The Of creates the observable from the arguments that you pass into it. You can pass any number of arguments to
the Of. Each argument emitted separately and one after the other. It sends the Complete signal in the end.

To use of you need to import it from rxjs library as shown below.


1
2 import { of } from 'rxjs';
3
observable from an array
Example of sending an array. Note that the entire array is emitted at once.
1
2 ngOnInit() {
3 const array=[1,2,3,4,5,6,7]
4 const obsof1=of(array);
5 obsof1.subscribe(val => console.log(val),
6 error=> console.log("error"),
7 () => console.log("complete"))
8
9 }
10
11
12 **** Output ***
13 [1, 2, 3, 4, 5, 6, 7]
14 complete
15
You can pass more than one array
1
2 ngOnInit() {
3 const array1=[1,2,3,4,5,6,7]
4 const array2=['a','b','c','d','e','f','g']
5 const obsof2=of(array1,array2 );
6 obsof2.subscribe(val => console.log(val),
7 error=> console.log("error"),
8 () => console.log("complete"))
9
10 }
11
12
13 **** Output ***
14 [1, 2, 3, 4, 5, 6, 7]
15 ['a','b','c','d','e','f','g']
16 complete
17
observable from a sequence of numbers
In the following example, we pass 1,2 & 3 as the argument to the from. Each emitted separately.
1
2 ngOnInit() {
3 const obsof3 = of(1, 2, 3);
4 obsof3.subscribe(val => console.log(val),
5 error => console.log("error"),
6 () => console.log("complete"))
7
8 }
9
10
11
12 **** Output ***
13 1
14 2
15 3
16 complete
17
observable from string
We pass two strings to the of method. Each argument is emitted as it is.
1
2 ngOnInit() {
3 const obsof4 = of('Hello', 'World');
4 obsof4.subscribe(val => console.log(val),
5 error => console.log("error"),
6 () => console.log("complete"))
7 }
8
9
10 **** Output ***
11 Hello
12 World
13 complete
14
observable from a value, array & string
We can pass anything to the Of operator. It justs emits it back one after the other.
1
2 ngOnInit() {
3 const obsof5 = of(100, [1, 2, 3, 4, 5, 6, 7],"Hello World");
4 obsof5.subscribe(val => console.log(val),
5 error => console.log("error"),
6 () => console.log("complete"))
7 }
8
9 **** Output ***
10 100
11 [1, 2, 3, 4, 5, 6, 7]
12 Hello World
13 complete
14
From Operator
From Operator takes only one argument that can be iterated and converts it into an observable.
You can use it to convert
an Array,
anything that behaves like an array
Promise
any iterable object
collections
any observable like object
It converts almost anything that can be iterated to an Observable.

To use from you need to import it from rxjs library as shown below.
1
2 import { from } from 'rxjs';
3
observable from an array
The following example converts an array into an observable. Note that each element of the array is iterated and
emitted separately.
1
2 ngOnInit() {
3
4 const array3 = [1, 2, 3, 4, 5, 6, 7]
5 const obsfrom1 = from(array3);
6 obsfrom1.subscribe(val => console.log(val),
7 error => console.log("error"),
8 () => console.log("complete"))
9
10 }
11
12 *** Output ****
13 1
14 2
15 3
16 4
17 5
18 6
19 7
20 complete
21
Observable from string
The from operator iterates over each character of the string and then emits it. The example is as shown below.
1
2 ngOnInit() {
3 const obsfrom2 = from('Hello World');
4 obsfrom2.subscribe(val => console.log(val),
5 error => console.log("error"),
6 () => console.log("complete"))
7 }
8
9
10 *** Output ****
11 H
12 e
13 l
14 l
15 o
16
17 W
18 o
19 r
20 l
21 d
22 complete
23
Observable from collection
Anything that can be iterated can be converted to observable. Here is an example using a collection.
1
2 ngOnInit() {
3 let myMap = new Map()
4 myMap.set(0, 'Hello')
5 myMap.set(1, 'World')
6 const obsFrom3 = from(myMap);
7 obsFrom3.subscribe(val => console.log(val),
8 error => console.log("error"),
9 () => console.log("complete"))
10 )
11
12 *** output ***
13 [0, "Hello"]
14 [1, "World"]
15 complete
16
Observable from iterable
Any Iterable types like Generator functions can be converted into an observable using from the operator.
1
2 ngOnInit() {
3 const obsFrom4 = from(this.generateNos())
4 obsFrom4.subscribe(val => console.log(val),
5 error => console.log("error"),
6 () => console.log("complete"))
7 }
8
9 *generateNos() {
10 var i = 0;
11 while (i < 5) {
12 i = i + 1;
13 yield i;
14 }
15
16
17 *** Output ***
18 1
19 2
20 3
21 4
22 5
23
Observable from promise
Use it to convert a Promise to an observable
1
2 ngOnInit() {
3 const promiseSource = from(new Promise(resolve => resolve('Hello World!')));
4 const obsFrom5 = from(promiseSource);
5 obsFrom5.subscribe(val => console.log(val),
6 error => console.log("error"),
7 () => console.log("complete"))
8 }
9
10 *** Output ****
11 Hello World
12 complete
13
Of Vs From
Of from

Accepts variable no of arguments Accepts only one argument

emits each argument as it is without changing anything iterates over the argument and emits each value

Create Observable from Event using FromEvent in Angular


Leave a Comment / 3 minutes of reading / January 24, 2021
Create observable from array, string, number, object & static data
Angular Observable pipe

Angular provides FromEvent method to create an observable from DOM events directly. In this article let us learn
how to do that by creating an observable from the button click event, keyup even & scroll events.
Table of Contents
Syntax
Example of fromEvent
How it works
fromevent from button click
fromevent from scroll
fromevent from keyup
Reference
Syntax
1
2 fromEvent<T>(target: FromEventTarget<T>,
3 eventName: string,
4 options: EventListenerOptions,
5 resultSelector: (...args: any[]) => T): Observable<T>
6
FromEventTarget is the first argument to fromevent. It can be a DOM EventTarget, Node.js EventEmitter, JQuery-like
event target, NodeList or HTMLCollection. The target must have a method to register/unregister the event handler.
(addEventListener/ removeEventListener in case of DOM Event target)
eventName is the second argument, which is a type of event we want to listen to.
Options are the additional argument that we want to pass to , when registering the event handler
i.e addEventListener
resultSelector is optional and will be deprecated in future versions.
Example of fromEvent
To create an observable from any event, first, we need to get the reference to DOM element using
the viewchild & ElementRef. For example the following code gets the reference to the button element with the
id #btn
1
2 //Template
3 <button #btn>Button</button>
4

1
2 //Component
3
4 @ViewChild('btn', { static: true }) button: ElementRef;
5
The code this.button.nativeElement returns the native DOM element. We pass this as the first argument to
the fromEvent to create an observable to the click event.
1
2 buttonClick() {
3 this.buttonSubscription = fromEvent(this.button.nativeElement, 'click')
4 .subscribe(res => console.log(res));
5 }
6
We can invoke the above method from the ngAfterViewInit method. Note that the @ViewChildwill not initialize
the btn element until the ngOnInit Hence we are using the ngAfterViewInit here.
1
2 ngAfterViewInit() {
3 this.buttonClick();
4 }
5
6
How it works
When we subscribe to an observable, which we created using the fromEvent method, it registers the event handler
using the addEventListener in the DOM element. Whenever the user clicks on the button, fromevent captures the
value and emits it to the subscriber as the first argument. When we unsubscribe, it unregisters the event handler
using the removeEventListener.
fromevent from button click
The following is the complete code of fromevent from a button click.
1
2 import { Component, Input, ViewChild, ElementRef, AfterViewInit, OnInit, OnDestroy } from '@angular/core';
3 import { Observable, of, from, fromEvent } from 'rxjs';
4 import { debounceTime } from 'rxjs/operators';
5
6 @Component({
7 selector: 'app-root',
8 templateUrl: './app.component.html',
9 styleUrls: ['./app.component.css']
10 })
11 export class AppComponent implements AfterViewInit , OnInit, OnDestroy {
12
13 title = 'Angular fromEvent Example';
14
15 @ViewChild('btn', { static: true }) button: ElementRef;
16
17 buttonSubscription
18
19 constructor(private elm: ElementRef) {
20 }
21
22 ngOnInit() {
23 }
24
25
26 ngAfterViewInit() {
27 this.buttonClick();
28 }
29
30
31 buttonClick() {
32 this.buttonSubscription = fromEvent(this.button.nativeElement, 'click')
33 .pipe(debounceTime(300))
34 .subscribe(res => console.log(res));
35 }
36
37
38 ngOnDestroy() {
39 this.buttonSubscription.unsubscribe()
40 }
41
42 }
43
fromevent from scroll
The following code shows how to create observable from the window scroll event
1
2 scroll() {
3 const source = fromEvent(window, 'scroll');
4 source.subscribe(val => console.log(val));
5 }
6
fromevent from keyup
The following code shows how to create observable from a keyUp event.
1
2 //Component
3
4 @ViewChild('name', { static: true }) name: ElementRef;
5
6 ngAfterViewInit() {
7 fromEvent(this.name.nativeElement, 'keyup')
8 .subscribe(res => console.log(res));
9 }
10
Using Angular observable pipe with example
3 Comments / 4 minutes of reading / July 2, 2020
Observable from event
Angular Map

The pipe method of the Angular Observable is used to chain multiple operators together. We can use the pipe as a
standalone method, which helps us to reuse it at multiple places or as an instance method. In this tutorial, we will
take a look at the pipe and learn how to use it in an Angular Application. We will show you examples
of pipe using map, filter & tap operators.

Table of Contents
RxJs Operators
Using pipe to combine operators
Pipe as an instance method
Example : Pipe with Map, Filter & Tap
Pipe as stand alone method
Example
References
RxJs Operators
The operators are very important components of the Rxjs library. They are functions that take an observable as input
and transform it into a new observable and return it. We use them to manipulate the observable data stream.
For Example.
Map operator applies a given project function to each value emitted by the source Observable and emits the
resulting values as an Observable.
Filter operator filter items from the source observable based on some condition and returns the filtered value as a
new observable

The following table lists some of the commonly used operators


AREA OPERATORS

Combination combineLatest, concat, merge, startWith , withLatestFrom, zip

Filtering debounceTime,
AREA OPERATORS

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

BEST ANGULAR BOOKS


The Top 8 Best Angular Books, which helps you to get started with Angular
Using pipe to combine operators
The pipe method accepts operators such as filter, map, as arguments. Each argument must be separated by a
comma. The order of the operators is important because when a user subscribes to an observable, the pipe executes
the operators in a sequence in which they are added.
There are two ways we can use the pipe. One as an instance of observable and the other way is to use if as
standalone method
To use observable we need it to import from the rxjs library. If you are intend to use the pipe standalone function,
then you also need to import it as well. All the operators are available in the library rxjs/operators.
1
2 import { Observable, of, pipe} from 'rxjs';
3 import { map, filter, tap } from 'rxjs/operators'
4
Pipe as an instance method
The pipe as an instance method is used as below. We the operators op1, op2 etc are passed as the argument
to pipe method. The output of op1 method becomes input of the op2 operator and so forth.
1
2 obs.pipe(
3 op1(),
4 op2(),
5 op3(),
6 op3(),
7)
8
Example : Pipe with Map, Filter & Tap
Here is the example of using pipe with map & filter operator.
1
2 import { Component, OnInit } from '@angular/core';
3 import { Observable, of} from 'rxjs';
4 import { map, filter, tap } from 'rxjs/operators'
5
6
7 @Component({
8 selector: 'app-root',
9 templateUrl: './app.component.html',
10 styleUrls: ['./app.component.css']
11 })
12 export class AppComponent implements OnInit {
13
14 obs = new Observable((observer) => {
15 observer.next(1)
16 observer.next(2)
17 observer.next(3)
18 observer.next(4)
19 observer.next(5)
20 observer.complete()
21 }).pipe(
22 filter(data => data > 2), //filter Operator
23 map((val) => {return val as number * 2}), //map operator
24 )
25
26 data = [];
27
28 ngOnInit() {
29 this.obs1.subscribe(
30 val => {
31 console.log(this.data)
32 }
33 )
34 }
35
36 }
37
38
39 //result
40 [6, 8, 10]
41
The following example makes use of pipe with map, filter & tap operator. The tap operator returns a new observable
which is a mirror copy of the source observable. We use it mostly for debugging purposes ( for example for logging
the values of observable as shown below).
1
2 import { Component, OnInit } from '@angular/core';
3 import { Observable, of, pipe } from 'rxjs';
4 import { map, filter, tap } from 'rxjs/operators'
5
6
7 @Component({
8 selector: 'app-root',
9 templateUrl: './app.component.html',
10 styleUrls: ['./app.component.css']
11 })
12 export class AppComponent implements OnInit {
13
14 obs = new Observable((observer) => {
15 observer.next(1)
16 observer.next(2)
17 observer.next(3)
18 observer.next(4)
19 observer.next(5)
20 observer.complete()
21 }).pipe(
22 tap(data => console.log('tap '+data)), //tap
23 filter(data => data > 2), //filter
24 tap(data => console.log('filter '+data)), //tap
25 map((val) => { return val as number * 2 }), //map
26 tap(data => console.log('final '+data)), //tap
27 )
28
29
30 data = [];
31
32 ngOnInit() {
33
34 this.obs.subscribe(
35 val => {
36 this.data.push(val)
37 console.log(this.data)
38 }
39 )
40
41 }
42 }
43
Pipe as stand alone method
We can also use the pipe as a standalone function to compose operators and re use the pipe at other places.
Example
1
2 import { Component, OnInit } from '@angular/core';
3 import { Observable, of, pipe } from 'rxjs';
4 import { map, filter, tap } from 'rxjs/operators'
5
6
7 @Component({
8 selector: 'app-root',
9 templateUrl: './app.component.html',
10 styleUrls: ['./app.component.css']
11 })
12 export class AppComponent implements OnInit {
13
14
15 customOperator = pipe(
16 tap(data => console.log('tap '+data)),
17 filter(data => data > 2),
18 tap(data => console.log('filter '+data)),
19 map((val) => {
20 return val as number * 2
21 }),
22 tap(data => console.log('final '+data)),
23 );
24
25
26 obs = new Observable((observer) => {
27 observer.next(1)
28 observer.next(2)
29 observer.next(3)
30 observer.next(4)
31 observer.next(5)
32 observer.complete()
33 }).pipe(
34 this.customOperator,
35 tap(data => console.log('final '+data)),
36 )
37
38
39 data = [];
40
41 ngOnInit() {
42
43 this.obs.subscribe(
44 val => {
45 this.data.push(val)
46 console.log(this.data)
47 }
48 )
49
50 }
51 }
52
You can also use the stand alone pipe as shown below.
1
2 customOperator = pipe(
3 tap(data => console.log('tap '+data)),
4 filter(data => data > 2),
5 tap(data => console.log('filter '+data)),
6 map((val) => {
7 return val as number * 2
8 }),
9 tap(data => console.log('final '+data)),
10 );
11
12
13 obs = new Observable((observer) => {
14 observer.next(1)
15 observer.next(2)
16 observer.next(3)
17 observer.next(4)
18 observer.next(5)
19 observer.complete()
20 })
21
22 ngOnInit() {
23 this.customOperator(this.obs).subscribe();
24 }
25
Using Map operator in Angular
3 Comments / 4 minutes of reading / January 26, 2021
Angular Observable pipe
Filter

The Angular observable Map operator takes an observable source as input. It applies a project function to each of
the values emitted by the source observable and transforms it into a new value. It then emits the new value to the
subscribers. We use a Map with a Pipe, which allows us to chain multiple operators together. In this guide, we’re
going to learn how to use the Map operator with examples like converting the source to upper case, Using Map the
Angular HTTP Request, with DOM events, filtering the input data, and using multiple Maps together, etc.

Table of Contents
Syntax
Using Observable Map
Map Examples
Convert input to upper case
Map to a Single Property
Using Map with HTTP Request
Using with event
map with filter
Multiple map
References
Syntax
The syntax of the map operator is as follows.
1
2 map<T, R>(project: (value: T, index: number) => R, thisArg?: any): OperatorFunction<T, R>
3
project: is a function that we use to manipulate the values emitted by the source observable. The project can accept
two arguments. one is value i.e. the value emitted by the observable. The second argument is index number.
The index number starts from 0 for the first value emitted and incremented by one for every subsequent value
emitted. It is similar to the index of an array.
thisArg: is optional and default is undefined.It defines what this is in the project function.
Using Observable Map
To use map first we need to import it from the rxjs/operators library.
1
2 import { map } from 'rxjs/operators'
3
Next, create an observable from array of numbers as shown below.
1
2 srcArray = from([1, 2, 3, 4]);
3
Use the pipe method to and invoke the map method.
1
2 multiplyBy2() {
3 this.srcArray
4 .pipe(map(val => { return val * 2}))
5 .subscribe(val => { console.log(val)})
6 }
7
The project function accepts only one argument val and returns it multiplied by 2.
1
2 map(val => { return val * 2})
3
Finally, we subscribe and print the result in console. The output is 2,4,6,8
The following image explains how values from the source observable ( i.e.1,2,3,4 ) go through the map which
transforms it into new values by multiplying it by 2.

BEST ANGULAR BOOKS


The Top 8 Best Angular Books, which helps you to get started with Angular
You can also access the second argument index as shown below. It starts as 0 for the first value and gets
incremented for every subsequent value
1
2 multiplyBy2() {
3
4 this.srcArray
5 .pipe(map((val, i) => { //index
6 console.log(i) //0
7 return val * 2;
8 }))
9 .subscribe(val => { console.log(val) })
10 }
11
Map Examples
Convert input to upper case
1
2 srcName$ = from(['John', 'Tom', 'Katy'])
3
4 toUpperCase() {
5 this.srcName$
6 .pipe(map(data => {
7 return data.toUpperCase();
8 }))
9 .subscribe(data => console.log(data))
10 }
11
Map to a Single Property
1
2 srcObject = from([
3 { fName: 'Sachin', lName: "Tendulkar" },
4 { fName: 'Rahul', lName: "Dravid" },
5 { fName: 'Saurav', lName: "Ganguly" },
6 ]);
7
8
9 MapToSingleProperty() {
10 this.srcObject
11 .pipe(map(data => { return data.fName + ' ' + data.lName }))
12 .subscribe(data => { console.log(data) })
13 }
14
15 //output
16 Sachin Tendulkar
17 Rahul Dravid
18 Saurav Ganguly
19
Using Map with HTTP Request
The following code gets the list of dogs breeds from the https://dog.ceo/api/breeds/list/all API and uses
the keyValue pipe to transform the object into an array of key-value pairs.
1
2 import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
3 import { Observable, from, pipe, fromEvent } from 'rxjs';
4 import { map, filter, tap } from 'rxjs/operators'
5 import { HttpClient } from '@angular/common/http';
6 import { KeyValuePipe } from '@angular/common';
7
8 @Component({
9 selector: 'app-root',
10 templateUrl: './app.component.html',
11 styleUrls: ['./app.component.css'],
12 providers: [KeyValuePipe]
13 })
14 export class AppComponent implements OnInit {
15
16 constructor(private http: HttpClient,
17 private keyValue: KeyValuePipe) {
18 }
19
20 @ViewChild('btn', { static: true }) button: ElementRef;
21
22 $dogsBreed(): Observable<any> {
23 return this.http.get<any>("https://dog.ceo/api/breeds/list/all")
24 }
25
26 getDogsBreed() {
27
28 this.$dogsBreed()
29 .pipe(map(data => {
30 var dogs = this.keyValue.transform(data.message)
31 console.log(dogs)
32 }))
33 .subscribe();
34
35 }
36 }
37
Using with event
You can create observable from event and use the map to transform the values.
1
2 buttonClick() {
3 fromEvent(this.button.nativeElement, 'click')
4 .pipe(map( ev => (ev as any).clientX))
5 .subscribe(res => console.log(res));
6 }
7
map with filter
1
2 srcArray = from([1, 2, 3, 4]);
3
4 filterWithMap() {
5 this.srcArray
6 .pipe(
7 filter(val => {
8 return val > 2;
9 }),
10 map((val, i) => {
11 return val * 2;
12 }))
13 .subscribe(val => { console.log(val) })
14 }
15
Multiple map
The following examples shows use of multiple map functions. The first map adds 10, while the second mad multiplies
by 2.
1
2 mulitpleMaps() {
3 this.srcArray
4 .pipe(
5 map(val => {
6 return val + 10;
7 }),
8 map((val, i) => {
9 return val * 2;
10 }))
11 .subscribe(val => { console.log(val) })
12 }
13
Filter Operator in Angular Observable
1 Comment / 2 minutes of reading / January 26, 2021
Angular Map
Angular Tap

The Filter Operator in Angular filters the items emitted by the source Observable by using a condition (predicate). It
emits only those values, which satisfies the condition and ignores the rest.

Table of Contents
Filter in Angular
Filter Example
Filter Empty or undefined
Filter object or array
Reference
Filter in Angular
Filter is the simplest and most used RxJs Operator in Angular. The Filter Operator takes 2 arguments.
Syntax
1
2 filter<T>(predicate: (value: T, index: number) => boolean, thisArg?: any): MonoTypeOperatorFunction<T>
3
The first argument is the predicate function. This function is evaluated against each value of the source observable.
Filter emits only those values which satisfies the the predicate. The predicate function takes 2 parameters. The first
one is the value emitted by the source. The second argument is zero based index.
The second argument thisArg is Optional. It determines the value of this in the predicate function
Filter Example
The following example filter function returns true only if the value is an even number.
1
2 import { Component } from "@angular/core";
3 import { filter } from "rxjs/operators";
4 import { interval, of, timer } from "rxjs";
5
6 @Component({
7 selector: "my-app",
8 template: `
9 <h1>Filter Example</h1>
10 `,
11 styleUrls: ["./app.component.css"]
12 })
13 export class AppComponent {
14 ngOnInit() {
15 of(1,2,3,4,5,6,7,8,9,10)
16 .pipe(
17 filter(val => {
18 return val %2==0;
19 }),
20 )
21 .subscribe(val => console.log(val));
22 }
23 }
24
25
26 ***Console***
27 2
28 4
29 6
30 8
31 10
32
33
Source Code
Filter Empty or undefined
1
2 filter(value => value !== undefined && value !== null)
3
Filter object or array
1
2 import { Component } from "@angular/core";
3 import { filter } from "rxjs/operators";
4 import { interval, of, timer } from "rxjs";
5 import { fromArray } from "rxjs/internal/observable/fromArray";
6
7 @Component({
8 selector: "my-app",
9 template: `
10 <h1>Filter Example</h1>
11 `,
12 styleUrls: ["./app.component.css"]
13 })
14 export class AppComponent {
15 values = [
16 {
17 name: "John",
18 age: 30
19 },
20 {
21 name: "alex",
22 age: 40
23 }
24 ];
25
26 ngOnInit() {
27 fromArray(this.values)
28 .pipe(
29 filter(val => {
30 return val.age > 30;
31 })
32 )
33 .subscribe(val => console.log(val));
34 }
35 }
36
37
Tap operator in Angular observable
Leave a Comment / 3 minutes of reading / January 26, 2021
Filter
SwitchMap

The Angular Tap RxJs operator returns an observable that is identical to the source. It does not modify the stream in
any way. Tap operator is useful for logging the value, debugging the stream for the correct values, or perform any
other side effects.

Syntax
1
2 tap(nextOrObserver: function, error: function, complete: function): Observable
3
Table of Contents
Tap Operator Example
Debugging the Observable
Error & Complete callbacks
Reference
Tap Operator Example
In the following example, we create an observable using the of operator. We use the pipe to chain the tap operator,
which just logs the values of the source observable into the console.
1
2 import { Component, VERSION } from "@angular/core";
3 import { tap } from "rxjs/operators";
4 import { of } from "rxjs";
5
6 @Component({
7 selector: "my-app",
8 template: `
9 <h1>Tap Example</h1>
10 `,
11 styleUrls: ["./app.component.css"]
12 })
13 export class AppComponent {
14 ngOnInit() {
15 of(1, 2, 3, 4, 5)
16 .pipe(
17 tap(val => {
18 console.log("Tap " + val);
19 })
20 )
21 .subscribe(val => console.log("at Subscriber " + val));
22 }
23
24 }
25
26
27
28
29 ***Console
30
31 Tap 1
32 at Subscriber 1
33 Tap 2
34 at Subscriber 2
35 Tap 3
36 at Subscriber 3
37 Tap 4
38 at Subscriber 4
39 Tap 5
40 at Subscriber 5
41
42
Source Code
if we simply pass the console.log function to the tap operator and the results will be same.
1
2 of(1, 2, 3, 4, 5)
3 .pipe(tap(console.log))
4 .subscribe(val => console.log("at Subscriber " + val));
5
Tap does not modify the source observable in any way
For Example changing the source any way in the tap operator as in the example below, will have no effect.
1
2 of(1, 2, 3, 4, 5)
3 .pipe(
4 tap(val => {
5 val=val+1
6 console.log("Tap " + val);
7 return val;
8 })
9 )
10 .subscribe(val => console.log("at Subscriber " + val));
11
Debugging the Observable
One of the use cases for the tap operator is using it to debug the Observable for the correct values.
The map operator in the following example, adds 5 to the source observable. To debug it, we can add the two tap
operators. One before and one after it and inspect the values.
1
2 of(1, 2, 3, 4, 5)
3 .pipe(
4 tap(val => {
5 console.log("before " +val);
6 }),
7 map(val => {
8 return val + 5;
9 }),
10 tap(val => {
11 console.log("after " +val);
12 })
13 )
14 .subscribe(val => console.log(val));
15
16
17
18 **Console**
19 before 1
20 after 6
21 6
22 before 2
23 after 7
24 7
25 before 3
26 after 8
27 8
28
Source Code
Error & Complete callbacks
We can also use the tap operator to log the error and complete callbacks as shown in the example below.
1
2 import { Component, VERSION } from "@angular/core";
3 import { FormControl, FormGroup } from "@angular/forms";
4 import { debounce, map, tap } from "rxjs/operators";
5 import { interval, of, Subscription } from "rxjs";
6
7 @Component({
8 selector: "my-app",
9 template: `
10 <h1>Tap Example</h1>
11
12
13 `,
14 styleUrls: ["./app.component.css"]
15 })
16 export class AppComponent {
17 ngOnInit() {
18 of(1, 2, 3, 4, 5)
19 .pipe(
20 tap(val => {
21
console.log("Before " + val);
22
}),
23
map(val => {
24
if (val == 3) {
25
throw Error;
26
}
27
return val + 5;
28
}),
29
tap(
30
val => {
31
console.log("After " + val);
32
},
33
err => {
34
console.log("Tap Error");
35
console.log(err);
36
},
37
() => {
38
console.log("Tap Complete");
39
}
40
)
41
)
42
.subscribe(val => console.log(val));
43
}
44
45
ngOnDestroy() {}
46
}
47
48
49
***Console ***
50
Before 1
51
After 6
52
6
53
Before 2
54
After 7
55
7
56
Before 3
57
Tap Error
58
ƒ Error()
59
60
ERROR
61
ƒ Error()
62
Using SwitchMap in Angular
9 Comments / 6 minutes of reading / May 16, 2021
Angular Tap
Angular MergeMap

The Angular SwitchMap maps each value from the source observable into an inner observable, subscribes to it, and
then starts emitting the values from it. It creates a new inner observable for every value it receives from the Source.
Whenever it creates a new inner observable it unsubscribes from all the previously created inner observables.
Basically it switches to the newest observable discarding all other.

Table of Contents
Syntax
SwitchMap Example
SwitchMap Vs Map
SwitchMap switches to the most recent observable
Using SwitchMap in Angular
With Route Parameters
Angular Forms ValueChanges event
References
Syntax
The syntax of the SwitchMap operator is as shown below.
1
2 switchMap(project: (value: T, index: number) => O): OperatorFunction<T, ObservedValueOf<O>>
3
project: is a function that we use to manipulate the values emitted by the source observable. The project can accept
two arguments. one is value i.e. the value emitted by the source observable. The second argument is index number.
The index number starts from 0 for the first value emitted and incremented by one for every subsequent value
emitted. It is similar to the index of an array. The project function must return an observable.
SwitchMap Example
To use SwitchMap in Angular first we need to import it our Component or Service.
1
2 import { switchMap } from 'rxjs/operators';
3
The following code shows how to use SwitchMap in Angular. We have two observables srcObservable which
emits 1,2,3,4 & innerObservable which emits 'A','B','C','D'.

BEST ANGULAR BOOKS


The Top 8 Best Angular Books, which helps you to get started with Angular
1
2 let srcObservable= of(1,2,3,4)
3 let innerObservable= of('A','B','C','D')
4
5 srcObservable.pipe(
6 switchMap( val => {
7 console.log('Source value '+val)
8 console.log('starting new observable')
9 return innerObservable
10 })
11 )
12 .subscribe(ret=> {
13 console.log('Recd ' + ret);
14 })
15
16
17 //Output
18 Source value 1
19 starting new observable
20 Recd A
21 Recd B
22 Recd C
23 Recd D
24 Source value 2
25 starting new observable
26 Recd A
27 Recd B
28 Recd C
29 Recd D
30 Source value 3
31 starting new observable
32 Recd A
33 Recd B
34 Recd C
35 Recd D
36 Source value 4
37 starting new observable
38 Recd A
39 Recd B
40 Recd C
41 Recd D
42
The project function is the first argument to the switchMap. It takes the values from the srcObservable. For each
value, it receives from the srcObservable (i. e. 1,2,3 &4) it creates a new observable i.e. innerObservable.
SwitchMap automatically subscribes to the innerObservable returned by the project function. The innerObservable
emits the values (A,B,C,D), and pushes it to the stream
Hence the subscribers will receive the values A, B, C, D four times. Once for each value of the srcObservable.
SwitchMap Vs Map
The map operators emits value as observable. The SwitchMap creates a inner observable, subscribes to it and emits
its value as observable.
The Following example shows the difference between them.
The map operator below maps the value coming from the source observable to a new value by multiplying it by 2. It
then emits it into the observable stream. The subscribers will receive the values 2,4,6 & 8.
1
2 let obs= of(1,2,3,4)
3
4 //Using MAP
5 obs.pipe(
6 map(val => {
7 return val*2 //Returning Value
8 })
9 )
10 .subscribe(ret=> {
11 console.log('Recd from map : ' + ret);
12 })
13
14 //Output
15 Recd from map : 2
16 Recd from map : 4
17 Recd from map : 6
18 Recd from map : 8
19
We can write the above code using SwitchMap as follows. The only thing that changes is how we return the new
value in the project function. The map example returns the value as val*2, while the SwitchMap returns new
observable (of(val*2)) using the of function. It also subscribes to the newly created observable and emits its value to
the stream.
1
2 let obs= of(1,2,3,4)
3
4 obs.pipe(
5 switchMap( val => {
6 return of(val*2) //Returning observable
7 })
8 )
9 .subscribe(ret=> {
10 console.log('Recd from switchMap : ' + ret);
11 })
12
13 //Output
14 Recd from switchMap : 2
15 Recd from switchMap : 4
16 Recd from switchMap : 6
17 Recd from switchMap : 8
18
SwitchMap switches to the most recent observable
Whenever SwitchMap subscribes to a new inner observable, it unsubscribes from the previous one.
In the following example, we create an observable from the click event of a button using the fromEvent method. The
SwitchMap operator returns an observable using the interval method. The interval method creates an infinite
observable, which emits a sequence of integers spaced by a given time interval.
1
2 import { Component, OnInit, ViewChild, AfterViewInit } from '@angular/core';
3 import { of, from, fromEvent, interval, Observable } from 'rxjs';
4 import { switchMap, map, catchError } from 'rxjs/operators';
5
6 @Component({
7 selector: 'app-root',
8 template: `<button #button>Click Me</button>`,
9 })
10 export class AppComponent implements AfterViewInit{
11
12 @ViewChild('button',{static:true}) button;
13 clicks$:Observable<any>;
14
15 ngAfterViewInit() {
16 this.clicks$ = fromEvent(this.button.nativeElement, 'click');
17 this.switchExample();
18 }
19
20 switchExample() {
21 this.clicks$
22 .pipe(
23 switchMap(() => {
24 return interval(500)
25 })
26 )
27 .subscribe( val => console.log(val));
28 }
29 }
30
When you click on the button, the clicks observable emits its first value. The switchMap replaces it with
the interval observable, which starts emitting value starting from 0 every 500ms.
When you click again, the switchMap unsubscribes from the previous interval observable and starts new one, which
again starts to emit value from 0.
Using SwitchMap in Angular
The following are some of the real use cases for the SwitchMap in Angular
With Route Parameters
When we use the Angular Router to Pass parameter to route, we need to read it in our component class. We do that
by subscribing to the paramMap to get the id. We then use the id to retrieve the product data.
The code is as shown below.
1
2 ngOnInit() {
3 this._Activatedroute.paramMap.subscribe(params => {
4 this.service.getProduct(+params.get('id'))
5 .subscribe((product: Product) => this.product = product);
6 });
7 }
8
Consider the example where the user navigates to the /product/1 route. The service will send the query to the
database to get the Product with id 1. Now, the user decides to navigate to the route /product/2. This will also result
in another query for the Product being sent to the database. It is possible that the result of the second query arrives
before the first query. In such a scenario, we will be in the route /product/2 , while our component displays the data
of the product 1.
We can easily solve the above issue using the switchMap. When SwitchMap creates the second observable it
unsubscribes from all the previous observable. Hence even if the Product 1 data arrives late, it would be discarded as
there are no subscribers
1
2 ngOnInit() {
3
4 this.activatedRoute.paramMap
5 .pipe(
6 switchMap((params: Params) => {
7 return this.service.getProduct(params.get('id'))
8 }
9 ))
10 .subscribe((product: Product) => this.product = product);
11 }
12
Angular Forms ValueChanges event
The similar situations described above can also happen when we subscribe to the ValueChanges event and use that
to get data from the back end.
1
2 this.mainForm.get("productCode").valueChanges
3 .pipe(
4 debounceTime(700)
5 )
6 .subscribe(val=> {
7 this.queryDepositData(val)
8 .subscribe(data => {
9 this.product=data;
10 })
11 })
12
The switchMap ensures that only the result from the last observable populates the Product
1
2 this.mainForm.get("productCode").valueChanges
3 .pipe(
4 debounceTime(700),
5 switchMap(val => {
6 return this.queryDepositData();
7 })
8 )
9 .subscribe(data => {
10 this.product=data;
11 })
12
The example also uses the debounceTime operator, which emits a value from the source Observable only after a
particular time span has passed without another source emission.
References
SwitchMap API
Read More
Pass Parameter to Route
ValueChanges in Angular
Using MergeMap in Angular
2 Comments / 6 minutes of reading / May 16, 2021
Angular SwitchMap
Angular ConcatMap
The Angular MergeMap maps each value from the source observable into an inner observable, subscribes to it, and
then starts emitting the values from it replacing the original value. It creates a new inner observable for every value
it receives from the Source. Unlike SwitchMap, MergeMap does not cancel any of its inner observables. It merges
the values from all of its inner observables and emits the values back into the stream.

Table of Contents
Syntax
MergeMap Example
MergeMap Vs Map
MergeMap combines results of inner observable
Using MergeMap in Angular
Merging values from two or more HTTP Calls
Using ForkJoin with MergeMap
References
Syntax
The syntax of the MergeMap operator is as shown below.
1
2 mergeMap(project: (value: T, index: number) => O): OperatorFunction<T, ObservedValueOf<O>>
3
project: is a function that we use to manipulate the values emitted by the source observable. The project function
accepts two arguments. one is value i.e. the value emitted by the source observable. The second argument
is index number. The index number starts from 0 for the first value emitted and incremented by one for every
subsequent value emitted. It is similar to the index of an array. The project function must return an observable.
MergeMap Example
To use MergeMap in Angular first we need to import it our Component or Service.
1
2 import { mergeMap } from 'rxjs/operators';
3
The following code shows how to use MergeMap in Angular. We have two observables srcObservable which
emits 1,2,3,4 & innerObservable which emits 'A','B','C','D'.
1
2 let srcObservable= of(1,2,3,4)
3 let innerObservable= of('A','B','C','D')
4
5 srcObservable.pipe(
6 mergeMap( val => {
7 console.log('Source value '+val)
8 console.log('starting new observable')
9 return innerObservable
10 })
11 )
12 .subscribe(ret=> {
13 console.log('Recd ' + ret);
14 })
15
16
17 //Output
18 Source value 1
19 starting new observable
20 Recd A
21 Recd B
22 Recd C
23 Recd D
24 Source value 2
25 starting new observable
26 Recd A
27 Recd B
28 Recd C
29 Recd D
30 Source value 3
31 starting new observable
32 Recd A
33 Recd B
34 Recd C
35 Recd D
36 Source value 4
37 starting new observable
38 Recd A
39 Recd B
40 Recd C
41 Recd D
42

BEST ANGULAR BOOKS


The Top 8 Best Angular Books, which helps you to get started with Angular
The project function is the first argument to the MergeMap. It takes the values from the srcObservable. For each
value, it receives from the srcObservable (i. e. 1,2,3 &4) it creates a new observable i.e. innerObservable.
MergeMap automatically subscribes to the innerObservable returned by the project function.
The innerObservable emits the values (A, B, C, D), and pushes it to the stream
Hence the subscribers will receive the values A, B, C, D four times. Once for each value of the srcObservable.
MergeMap Vs Map
The map operators emit value as observable. The MergeMap creates an inner observable, subscribes to it, and emits
its value as observable.
The Following example shows the difference between MergeMap & Map.
The Map operator below maps the value coming from the source observable to a new value by multiplying it by 2. It
then emits it into the observable stream. The subscribers will receive the values 2, 4, 6 & 8.
1
2 let obs= of(1,2,3,4)
3
4 //Using MAP
5 obs.pipe(
6 map(val => {
7 return val*2 //Returning Value
8 })
9 )
10 .subscribe(ret=> {
11 console.log('Recd from map : ' + ret);
12 })
13
14 //Output
15 Recd from map : 2
16 Recd from map : 4
17 Recd from map : 6
18 Recd from map : 8
19
We can achieve the same using the MergeMap also. The only thing that changes is how we return the new value
from our project function. The map returns the value as val*2, while the MergeMap returns the value as observable
(of(val*2)) using the of function. It also subscribes to the newly created observable and emits its value to the stream.
1
2 let obs= of(1,2,3,4)
3
4 obs.pipe(
5 mergeMap( val => {
6 return of(val*2) //Returning observable
7 })
8 )
9 .subscribe(ret=> {
10 console.log('Recd from mergeMap : ' + ret);
11 })
12
13 //Output
14 Recd from mergeMap: 2
15 Recd from mergeMap: 4
16 Recd from mergeMap: 6
17 Recd from mergeMap: 8
18
MergeMap combines results of inner observable
MergeMap never cancels any of its inner observable. It waits for them to finish and emit value. Note that the inner
observable’s might finish in an order that is different from the order in which they are subscribed. MergeMap does
not care about the order.
In the following example, we create an observable from the click event of a button using the fromEvent method. On
every click of the button, the MergeMap operator returns an inner observable delayedObs
The delayedObs emits 5 values separated by 1000 ms.
1
2 import { Component, OnInit, ViewChild, AfterViewInit } from '@angular/core';
3 import { of, from, fromEvent, interval, Observable } from 'rxjs';
4 import { switchMap, map, catchError } from 'rxjs/operators';
5
6 @Component({
7 selector: 'app-root',
8 template: `<button #button>Click Me</button>`,
9 })
10 export class AppComponent implements AfterViewInit{
11
12 @ViewChild('button',{static:true}) button;
13 clicks$:Observable<any>;
14
15 ngAfterViewInit() {
16 this.clicks$ = fromEvent(this.button.nativeElement, 'click');
17 this.mergeMapExample();
18 }
19
20 delayedObs(count:number) {
21 return new Observable((observer) => {
22 setTimeout(() => { observer.next(count+" A") }, 1000);
23 setTimeout(() => { observer.next(count+" B") }, 2000);
24 setTimeout(() => { observer.next(count+" C") }, 3000);
25 setTimeout(() => { observer.next(count+" D") }, 4000);
26 setTimeout(() => { observer.next(count+" E"); observer.complete() }, 5000);
27 })
28 }
29
30 mergeMapExample() {
31
32 let obs=
33
34 this.clicks$
35 .pipe(
36 mergeMap(() => {
37 this.count=this.count+1;
38 return this.delayedObs(this.count)
39 })
40 )
41 .subscribe(val => console.log(val));
42 }
43
44 }
45
When you click on the button, the clicks observable emits its first value. Inside the MergeMap we increase the count
by 1 and pass it to the delayedObs. The mergeMap subscribes to the delayedObs. It starts emitting values A to E
prepended by the count.
When you click again, the mergeMap again subscribes to the delayedObs and it starts to emit the values again.
The mergeMap collects all the emitted values as they arrive from all of its inner observables and emits it into the
subscribers.

Using MergeMap in Angular


The following are some of the real use cases for the MergeMap in Angular
Merging values from two or more HTTP Calls
Consider a scenario where you receive data from an observable (outer observable). For each of those values, you
want to call another observable (inner observable) to get more data. The scenario like this is an ideal use case for
MergeMap
In the following example, we have an array of a breed of dogs. We convert the array into an observable. This
becomes our outer observable
For each of those dog breeds emitted by the outer observable, we make an HTTP request to get the sub-breeds using
the free Dog API. The URL for the HTTP request constructed using the dog breed, which we receive from the outer
observable.
The MergeMap automatically subscribes to all of its inner observable and waits for them to complete. It then pushes
the values from them into the subscribers.
1
2 of("hound", "mastiff", "retriever") //outer observable
3 .pipe(
4 mergeMap(breed => {
5 const url = 'https://dog.ceo/api/breed/' + breed + '/list';
6 return this.http.get<any>(url) //inner observable
7 })
8 )
9 .subscribe(data => {
10 console.log(data)
11 })
12
The above code, without using the MergeMap is as follows. The code makes use of nested observable.
1
2 of("hound", "mastiff", "retriever")
3 .subscribe(breed => {
4 const url = 'https://dog.ceo/api/breed/' + breed + '/list';
5
6 this.http.get<any>(url)
7 .subscribe(data => {
8 console.log(data)
9 })
10 })
11
Using ForkJoin with MergeMap
The MergeMap create a one inner observable for each value of outer observable. To Create more than one inner
observable, we can make use of the ForkJoin Operator.
In the following example, along with a list of breeds, we also send a query for a random image of the dog breed. This
requires us to send two HTTP get request in Angular. We create two observables obs1 & obs2 to do that. Then we
use the forJoin to merge obs1 with obs2 and return a new observable.
1
2 MergeHTTPRequestWithFork() {
3
4 //const url='https://dog.ceo/api/breed/'+hound+'/list';
5
6 of("hound", "mastiff", "retriever")
7 .pipe(
8 mergeMap(breed => {
9 const url1 = 'https://dog.ceo/api/breed/' + breed + '/list';
10 const url2 = 'https://dog.ceo/api/breed/' + breed + '/images/random';
11
12 let obs1= this.http.get<any>(url1)
13 let obs2= this.http.get<any>(url2)
14
15 return forkJoin(obs1,obs2)
16
17
})
18
)
19
.subscribe(data => {
20
console.log(data)
21
})
22
23
}
24
Using concatMap in Angular
2 Comments / 7 minutes of reading / May 16, 2021
Angular MergeMap
Angular exhaustMap

The Angular ConcatMap maps each value from the source observable into an inner observable, subscribes to it, and
then starts emitting the values from it replacing the original value. It creates a new inner observable for every value
it receives from the Source. It merges the values from all of its inner observables in the order in which they are
subscribed and emits the values back into the stream. Unlike SwitchMap, ConcatMap does not cancel any of its inner
observables. It is Similar to MergeMap except for one difference that it maintains the order of its inner observables.

Table of Contents
Syntax
ConcatMap Example
ConcatMap Vs Map
ConcatMap combines inner observable and keeps the order
Using ConcatMap in Angular
Merging values from two or more HTTP Calls
Using ForkJoin with ConcatMap
References
Syntax
The syntax of the concatMap operator is as shown below.
1
2 concatMap(project: (value: T, index: number) => O): OperatorFunction<T, ObservedValueOf<O>>
3
project: is a function that we use to manipulate the values emitted by the source observable. The project function
accepts two arguments. one is value i.e. the value emitted by the source observable. The second argument
is index number. The index number starts from 0 for the first value emitted and incremented by one for every
subsequent value emitted. It is similar to the index of an array. The project function must return an observable.
ConcatMap Example
To use concatMap in Angular first we need to import it our Component or Service.
1
2 import { concatMap } from 'rxjs/operators';
3
In the following code, we have two observables srcObservable which emits 1,2,3,4 & innerObservable which
emits 'A','B','C','D'.
1
2 let srcObservable= of(1,2,3,4)
3 let innerObservable= of('A','B','C','D')
4
5 srcObservable.pipe(
6 concatMap( val => {
7 console.log('Source value '+val)
8 console.log('starting new observable')
9 return innerObservable
10 })
11 )
12 .subscribe(ret=> {
13 console.log('Recd ' + ret);
14 })
15
16
17 //Output
18 Source value 1
19 starting new observable
20 Recd A
21 Recd B
22 Recd C
23 Recd D
24 Source value 2
25 starting new observable
26 Recd A
27 Recd B
28 Recd C
29 Recd D
30 Source value 3
31 starting new observable
32 Recd A
33 Recd B
34 Recd C
35 Recd D
36 Source value 4
37 starting new observable
38 Recd A
39 Recd B
40 Recd C
41 Recd D
42

BEST ANGULAR BOOKS


The Top 8 Best Angular Books, which helps you to get started with Angular
The ConcatMap receives its values from the srcObservable. For each value, it creates a new observable
i.e. innerObservable. It also automatically subscribes to the innerObservable. The innerObservable emits the values
(A, B, C, D), and pushes it to the subscribers.
The ConcactMap differs from the MergeMap, the way it handles the inner observable. ConcatMap always waits for
the previous inner observable to finish before creating a new observble. This will ensure that the subscribers will
receive the data in the order in which the observable’s are subscribed.
Hence the subscribers will receive the values A, B, C, D four times. Once for each value of the srcObservable.
ConcatMap Vs Map
The map operators emit value as observable. The ConcatMap creates an inner observable, subscribes to it, and emits
its value as observable. It emits the value in the order in which it creates the observable.
The Following example shows the difference between ConcatMap & Map.
The Map operator below maps the value coming from the source observable to a new value by multiplying it by 2. It
then emits it into the observable stream. The subscribers will receive the values 2, 4, 6 & 8.
1
2 let obs= of(1,2,3,4)
3
4 //Using MAP
5 obs.pipe(
6 map(val => {
7 return val*2 //Returning Value
8 })
9 )
10 .subscribe(ret=> {
11 console.log('Recd from map : ' + ret);
12 })
13
14 //Output
15 Recd from map : 2
16 Recd from map : 4
17 Recd from map : 6
18 Recd from map : 8
19
In the ConcatMap example, only thing that changes is how we return the new value from our project function.
The map returns the value as val*2, while the concatMap returns the value as observable (of(val*2)) using
the of function. It also subscribes to the newly created observable and emits its value to the stream.
1
2 let obs= of(1,2,3,4)
3
4 obs.pipe(
5 concatMap( val => {
6 return of(val*2) //Returning observable
7 })
8 )
9 .subscribe(ret=> {
10 console.log('Recd from concatMap : ' + ret);
11 })
12
13 //Output
14 Recd from concatMap: 2
15 Recd from concatMap: 4
16 Recd from concatMap: 6
17 Recd from concatMap: 8
18
ConcatMap combines inner observable and keeps the order
ConcatMap never cancels any of its inner observable. It waits for them to finish and emit value. It also waits for the
previous inner observable to finish before creating a new observable.
In the following example, we create an observable from the click event of a button using the fromEvent method. On
every click of the button, the ConcatMap operator returns an inner observable delayedObs
The delayedObs emits 5 values separated by 1000 ms.
1
2 import { Component, OnInit, ViewChild, AfterViewInit } from '@angular/core';
3 import { of, from, fromEvent, interval, Observable } from 'rxjs';
4 import { switchMap, map, catchError } from 'rxjs/operators';
5
6 @Component({
7 selector: 'app-root',
8 template: `<button #button>Click Me</button>`,
9 })
10 export class AppComponent implements AfterViewInit{
11
12 @ViewChild('button',{static:true}) button;
13 clicks$:Observable<any>;
14
15 ngAfterViewInit() {
16 this.clicks$ = fromEvent(this.button.nativeElement, 'click');
17 this.concatMapExample3();
18 }
19
20 delayedObs(count:number) {
21 return new Observable((observer) => {
22 setTimeout(() => { observer.next(count+" A") }, 1000);
23 setTimeout(() => { observer.next(count+" B") }, 2000);
24 setTimeout(() => { observer.next(count+" C") }, 3000);
25 setTimeout(() => { observer.next(count+" D") }, 4000);
26 setTimeout(() => { observer.next(count+" E"); observer.complete() }, 5000);
27 })
28 }
29
30 concatMapExample3() {
31
32 let obs=
33
34 this.clicks$
35 .pipe(
36 concatMap(() => {
37 this.count=this.count+1;
38 return this.delayedObs(this.count)
39 })
40 )
41 .subscribe(val => console.log(val));
42 }
43
44 }
45
When you click on the button, the clicks observable emits its first value. Inside the concatMap we increase the count
by 1 and pass it to the delayedObs. The concatMap subscribes to the delayedObs. It starts emitting values A to E
prepended by the count.
When you click again, the concatMap checks if the previous observable has finished. If not it waits for it to finish
before subscribing to the delayedObs
The concatMap collects all the emitted values from all of its inner observables and emits it into the subscribers.
You can verify from the following result that even though we click multiple times on the click button, the results
always appear in the correct order.
Using ConcatMap in Angular
The following are some of the real use cases for the concatMap in Angular
Merging values from two or more HTTP Calls
Consider a scenario where you receive data from an observable (outer observable). For each of those values, you
want to call another observable (inner observable) to get more data. The scenario like this is an ideal use case for
ConcatMap
In the following example, we have an array of a breed of dogs. We convert the array into an observable. This
becomes our outer observable
For each of those dog breeds emitted by the outer observable, we make an HTTP request to get the sub-breeds using
the free Dog API. The URL for the HTTP request constructed using the dog breed, which we receive from the outer
observable.
The ConcatMap automatically subscribes to all of its inner observable and waits for them to complete. It then pushes
the values from them into the subscribers.
1
2 of("hound", "mastiff", "retriever") //outer observable
3 .pipe(
4 concatMap(breed => {
5 const url = 'https://dog.ceo/api/breed/' + breed + '/list';
6 return this.http.get<any>(url) //inner observable
7 })
8 )
9 .subscribe(data => {
10 console.log(data)
11 })
12
The above code, without using the concatMap is as follows. The code makes use of nested observable.
1
2 of("hound", "mastiff", "retriever")
3 .subscribe(breed => {
4 const url = 'https://dog.ceo/api/breed/' + breed + '/list';
5
6 this.http.get<any>(url)
7 .subscribe(data => {
8 console.log(data)
9 })
10 })
11
Using ForkJoin with ConcatMap
The ConcatMap create a one inner observable for each value of outer observable. To Create more than one inner
observable, we can make use of the ForkJoin Operator.
In the following example, along with a list of breeds, we also send a query for a random image of the dog breed. This
requires us to send two HTTP get request in Angular. We create two observables obs1 & obs2 to do that. Then we
use the forJoin to merge obs1 with obs2 and return a new observable.
1
2 MergeHTTPRequestWithFork() {
3
4 //const url='https://dog.ceo/api/breed/'+hound+'/list';
5
6 of("hound", "mastiff", "retriever")
7 .pipe(
8 concatMap(breed => {
9 const url1 = 'https://dog.ceo/api/breed/' + breed + '/list';
10 const url2 = 'https://dog.ceo/api/breed/' + breed + '/images/random';
11
12 let obs1= this.http.get<any>(url1)
13 let obs2= this.http.get<any>(url2)
14
15 return forkJoin(obs1,obs2)
16
17 })
18 )
19 .subscribe(data => {
20 console.log(data)
21 })
22
23 }
24
Using ExhaustMap in Angular
Leave a Comment / 4 minutes of reading / May 16, 2021
Angular ConcatMap
Take, TakeUntil, takeWhile & TakeLast

The Angular ExhaustMap maps each value from the source observable into an inner observable, subscribes to it. It
then starts emitting the values from it replacing the original value. It then waits for the inner observable to finish. If it
receives any new values before the completion of the inner observable it ignores it. It receives a new value after
completion of the inner observable, then it creates a new inner observable. The whole process repeats itself until
the source observable is completes

Table of Contents
Syntax
ExhaustMap Example
ExhaustMap waits for the inner observable to finish
Using ExhaustMap in Angular
References
Syntax
The syntax of the exhaustMap operator is as shown below.
1
2 exhaustMap(project: (value: T, index: number) => O): OperatorFunction<T, ObservedValueOf<O>>
3
project: is a function that we use to manipulate the values emitted by the source observable. The project function
accepts two arguments. one is value i.e. the value emitted by the source observable. The second argument
is index number. The index number starts from 0 for the first value emitted and incremented by one for every
subsequent value emitted. It is similar to the index of an array. The project function must return an observable.
ExhaustMap Example
To use ExhaustMap in Angular first we need to import it our Component or Service.
1
2 import { exhaustMap} from 'rxjs/operators';
3
In the following code, we have two observables srcObservable which emits 1,2,3,4 & innerObservable which
emits 'A','B','C','D'.

BEST ANGULAR BOOKS


The Top 8 Best Angular Books, which helps you to get started with Angular
1
2 let srcObservable= of(1,2,3,4)
3 let innerObservable= of('A','B','C','D')
4
5 srcObservable.pipe(
6 exhaustMap( val => {
7 console.log('Source value '+val)
8 console.log('starting new observable')
9 return innerObservable
10 })
11 )
12 .subscribe(ret=> {
13 console.log('Recd ' + ret);
14 })
15
16
17 //Output
18 Source value 1
19 starting new observable
20 Recd A
21 Recd B
22 Recd C
23 Recd D
24 Source value 2
25 starting new observable
26 Recd A
27 Recd B
28 Recd C
29 Recd D
30 Source value 3
31 starting new observable
32 Recd A
33 Recd B
34 Recd C
35 Recd D
36 Source value 4
37 starting new observable
38 Recd A
39 Recd B
40 Recd C
41 Recd D
42
The ExhaustMap receives its values from the srcObservable. For each value, it creates a new observable
i.e. innerObservable. It also automatically subscribes to the innerObservable. The innerObservable emits the values
(A, B, C, D), and pushes it to the subscribers.
The ExhaustMap differs from the MergeMap, SwitchMap & ConcatMap the way it handles the inner observable.
ExhaustMap always waits for the inner observable to finish. It ignores any value it receives from the source during
this period. Any value it receives after the inner observable is finished is accepted and it creates a new inner
observable.
This difference is becomes clear in the next example.
ExhaustMap waits for the inner observable to finish
ExhaustMap creates and waits for inner observable before resuming.
In the following example, we create an observable from the click event of a button using the fromEvent method. On
every click of the button, the ExhaustMap operator returns an inner observable delayedObs
The delayedObs emits 5 values separated by 1000 ms.
1
2 import { Component, OnInit, ViewChild, AfterViewInit } from '@angular/core';
3 import { of, from, fromEvent, interval, Observable } from 'rxjs';
4 import { switchMap, map, catchError } from 'rxjs/operators';
5
6 @Component({
7 selector: 'app-root',
8 template: `<button #button>Click Me</button>`,
9 })
10 export class AppComponent implements AfterViewInit{
11
12 @ViewChild('button',{static:true}) button;
13 clicks$:Observable<any>;
14
15 ngAfterViewInit() {
16 this.clicks$ = fromEvent(this.button.nativeElement, 'click');
17 this.exhaustMapExample3();
18 }
19
20 delayedObs(count:number) {
21 return new Observable((observer) => {
22 setTimeout(() => { observer.next(count+" A") }, 1000);
23 setTimeout(() => { observer.next(count+" B") }, 2000);
24 setTimeout(() => { observer.next(count+" C") }, 3000);
25 setTimeout(() => { observer.next(count+" D") }, 4000);
26 setTimeout(() => { observer.next(count+" E"); observer.complete() }, 5000);
27 })
28 }
29
30 exhaustMapExample3() {
31
32 let obs=
33
34 this.clicks$
35 .pipe(
36 exhaustMap(() => {
37 this.count=this.count+1;
38 return this.delayedObs(this.count)
39 })
40 )
41 .subscribe(val => console.log(val));
42 }
43
44 }
45
When you click on the button, the clicks observable emits its first value. Inside the exhaustMapwe increase the count
by 1 and pass it to the delayedObs. The exhaustMapsubscribes to the delayedObs. It starts emitting values A to E
prepended by the count.
When you click again, the exhaustMapchecks to see if the previous observable has finished. If not it ignore the value.
You can verify it from the following result. When we click multiple times, it ignores the values when the inner
observable is running.

Using ExhaustMap in Angular


The exhaustMap is useful in scenarios, where you want to prevent submission of duplicate values
For Example, the user clicking on the Submit button twice will trigger two HTTP calls to the back end. The
ExhaustMap will prevent the creation of new HTTP call until the previous one finishes
Take, TakeUntil, TakeWhile & TakeLast in Angular Observable
1 Comment / 5 minutes of reading / January 26, 2021
Angular ExhaustMap
First, Last & Single

The take, takeUntil, takeWhile & takeLast operators allow us to filter out the emitted values from the observable.
The take(n) emits the first n values, while takeLast(n) emits the last n values. The takeUntil(notifier) keeps emitting
the values until it is notified to stop. takeWhile(predicate) emits the value while values satisfy the predicate. All of
the stops emitting once done.

Table of Contents
Take
TakeUntil
TakeWhile
TakeWhile Vs Filter
TakeLast
References
Take
Take operator emits the first n number of values before completing. Any reminder values are ignored.
Syntax
take(n)
Where n is the maximum number of values to emit.
If the source emits more than n values, then take emits only n values and completes
If the source emits less than n number of values, then take emits all of them before completing.
Example
app.component.ts
1
2 import { Component, VERSION } from "@angular/core";
3 import { of } from "rxjs";
4 import { take } from "rxjs/operators";
5
6 @Component({
7 selector: "my-app",
8 templateUrl: "./app.component.html",
9 styleUrls: ["./app.component.css"]
10 })
11 export class AppComponent {
12
13 obs = of(1, 2, 3, 4, 5).pipe(take(2));
14
15 ngOnInit() {
16 this.obs.subscribe(val => console.log(val));
17 }
18 }
19
20
21
22 ****Console ******
23 1
24 2
25
Source Code
1
2
3 export class AppComponent {
4
5 takeFive = interval(1000).pipe(take(5));
6
7 ngOnInit() {
8 this.takeFive.subscribe(val => console.log(val));
9 }
10 }
11
12
13 ****Console ******
14 0
15 1
16 2
17 3
18 4
19
TakeUntil
The takeUntil operator returns an Observable that emits value from the source Observable until
the notifier Observable emits a value.
Syntax
1
2 TakeUntil(notifier: Observable): Observable
3
We must pass a notifier observable as the argument to the TakeUntil Operator
TakeUntil emits the values from the Source Observable as long as it does not receive any value from the notifier
observable
When the notifier emits a value, the TakeUntil completes the Source observable.
If the notifier completes without emitting any value, then the TakeUntil keeps emitting values from the source and
completes when the source completes.
Example
In the example below, we create a notifier observable
1
2 notifier= new Subject();
3
The notifier observable emits a value , when use clicks on the stop button.
1
2 stopObs() {
3 this.notifier.next();
4 this.notifier.complete();
5 }
6
Use the takeUntil in the source observable as shown below
1
2 obs = interval(1000).pipe(takeUntil(this.notifier));
3
Run the app. The source observable stops when you click on stop button.
app.component.ts
1
2 import { Component, VERSION } from "@angular/core";
3 import { of, interval, Subject, Observable } from "rxjs";
4 import { take, takeUntil, tap } from "rxjs/operators";
5
6 @Component({
7 selector: "my-app",
8 templateUrl: "./app.component.html",
9 styleUrls: ["./app.component.css"]
10 })
11 export class AppComponent {
12 notifier = new Subject();
13
14 obs = interval(1000).pipe(takeUntil(this.notifier));
15
16 ngOnInit() {
17 this.obs.subscribe(val => console.log(val));
18 }
19
20 stopObs() {
21 this.notifier.next();
22 this.notifier.complete();
23 }
24 }
25
Source Code
app.component.html
1
2 <h1>TakeUntil Example</h1>
3
4 <button (click)="stopObs()">Stop</button>
5 <br>
6
7
Source Code
One of the use cases of takeUntil is to automatically unsubscribe all the observables. You can refer to it from the
tutorial on Unsubscribing from an observable.
TakeWhile
TakeWhile operator will keep emitting the value from the source observable as long as they pass the given condition
(predicate). When it receives a value that does not satisfy the condition it completes the observable. No further
values are emitted even if they satisfy the condition.
Syntax
1
2 takeWhile(predicate: function(value, index): boolean,
3 inclusive?: boolean): Observable
4
Where predicate is the condition.
If inclusive is true, then the emits the value, which does not pass the condition before terminating the observable.
Example
In the code below takeWhile tests the condition val < 3 against the incoming values. When it receives the value 3,
which does not satisfy the condition, the observable completes. It does not emit any further values although the
stream still has values that satisfy the condition.
1
2 import { Component, VERSION } from "@angular/core";
3 import { of, interval, Subject, Observable } from "rxjs";
4 import { take, takeUntil, takeWhile, tap } from "rxjs/operators";
5
6 @Component({
7 selector: "my-app",
8 templateUrl: "./app.component.html",
9 styleUrls: ["./app.component.css"]
10 })
11 export class AppComponent {
12 obs = of(1, 2, 3, 1, 2, 3, 1, 2, 3)
13 .pipe(
14 takeWhile(val => val < 3)
15 );
16
17 ngOnInit() {
18 this.obs.subscribe(val => console.log(val));
19 }
20 }
21
22
23 *** Console ***
24 1
25 2
26
27
Source Code
With inclusive is set to true, takewhile also emits the value 3 before completing the observable.
1
2 export class AppComponent {
3 obs = of(1, 2, 3, 1, 2, 3, 1, 2, 3)
4 .pipe(
5 takeWhile(val => val < 3, true)
6 );
7
8 ngOnInit() {
9 this.obs.subscribe(val => console.log(val));
10 }
11 }
12
13 *** Console ***
14 1
15 2
16 3
17
Source Code
Example
1
2 evenNumbers = of(2, 4, 6, 3, 8)
3 .pipe(takeWhile(n => n % 2 == 0))
4 .subscribe(val => console.log(val));
5
6 **Console ***
7 2
8 4
9 6
10
11 //8 is not emitted
12
TakeWhile Vs Filter
Both takeWhile & filter uses the condition to filter out the incoming stream. Both allows only the matching values to
pass through discarding the others.
The difference is that takeWhile discards the rest of the stream, when it receives the first value that does not satisfy
the condition (If the inclusive is set to true, then it also emits the last value even when it does not satisfy the
condition). The filter operator never stops the observable.
The following example, filter operator does not stop when it receives the value 3. But it discards it and continues
further until the stream itself completes.
Example
1
2 obs = of(1, 2, 3, 1, 2, 3, 1, 2, 3)
3 .pipe(
4 filter(val => val < 3, true)
5 );
6
7 ngOnInit() {
8 this.obs.subscribe(val => console.log(val));
9 }
10
11
12 ***Console ****
13 1
14 2
15 1
16 2
17 1
18 2
19
Source Code
TakeLast
TakeLast operator emits the last n number of values from the source observable.
Syntax
1
2 takeLast<T>(n: number)
3
Where n is the maximum number of values to emit.
To know the last n number of values, the TakeLast needs to wait for the source to complete. Hence if the source
never completes, then TakeLast will never emit a value.
When the stream completes, the takeLast will
emits the last n number of values
if the source emits less than the n number of values then it emits all of them
stream completes immediatly
Example
1
2 import { Component, VERSION } from "@angular/core";
3 import { of, range, Observable } from "rxjs";
4 import { takeLast } from "rxjs/operators";
5
6 @Component({
7 selector: "my-app",
8 templateUrl: "./app.component.html",
9 styleUrls: ["./app.component.css"]
10 })
11 export class AppComponent {
12 obs = range(1, 100).pipe(takeLast(3));
13
14 ngOnInit() {
15 this.obs.subscribe(val => console.log(val));
16 }
17 }
18
19 ***Console****
20 98
21 99
22 100
23
Source Code
References
take
takeUntil
takeWhile
takeLast
First, Last & Single Operator in Angular Observable
1 Comment / 5 minutes of reading / January 26, 2021
Take, TakeUntil, TakeWhile, TakeLast
Skip, SkipUntil, SkipWhile & SkipLast

In the tutorial, let us learn the First, Last & Single RxJs operators in Angular Observable. All three operators use the
predicate (condition) to check the values of the source observable. The first emits the first matching value, the Last
emits the last matching value & the Single emits only if a single value matches the predicate.

Table of Contents
First Operator
First Vs Take(1)
Last Operator
Last Vs TakeLast(1)
Single
References
First Operator
The first operator emits the first value that meets the condition. If no condition is specified, then it will emit the first
value it receives.
Syntax
1
first<T, D>(predicate?: (value: T, index: number, source: Observable<T>) => boolean, defaultValue?: D) :
2
OperatorFunction<T, T | D>
3
Where
predicate: is the condition to match
defaultValue: is the value to emit if no value matches the condition
Emits the first value if no predicate is present
Emits the first matching value if the predicate is present
Closes the stream after emitting a value
If the source completes before emitting any matching value, then it raises the error notification.
Example
In the following example, we create an observable using the of operator. The first operator here emits the first value
it receives i.e 1 and then it completes.
1
2 import { Component, VERSION } from "@angular/core";
3 import { timer, interval, of } from "rxjs";
4 import { first } from "rxjs/operators";
5
6 @Component({
7 selector: "my-app",
8 templateUrl: "./app.component.html",
9 styleUrls: ["./app.component.css"]
10 })
11 export class AppComponent {
12 src = of(1, 2, 3, 4, 5).pipe(first());
13
14 id = Date.now();
15
16 constructor() {}
17
18 ngOnInit() {
19 console.log("Component Created " + this.id);
20
21 this.src.subscribe(value => {
22 console.log(value);
23 });
24 }
25 }
26
27
28 *** Result ****
29 1
30
Source Code
Emits the first value that matches
1
2 src = of(1, 2, 3, 4, 5).pipe(first(val => val > 3));
3
4
5 **Result**
64
7
Source Code
The following code returns an error as no value matches the condition.
1
2 src = of(1, 2, 3, 4, 5).pipe(first(val => val > 10));
3
4
5 ***Error
6 no elements in sequence
7
Source Code
But first with the default value, will emit the default value if no value matches the condition.
1
2 src = of(1, 2, 3, 4, 5).pipe(first(val => val > 10,100));
3
4
5 ***Console**
6 100
7
The following also results in an error, as the source does not emit any values
1
2 src = of().pipe(first());
3
4
5 ***Error
6 no elements in sequence
7
The following emits the default value 100
1
2 src = of().pipe(first(val => true, 100));
3
4
5 ***Console
6 100
7
First Vs Take(1)
The first() (without condition & default value) and take(1) returns the first value they receive from the source and
closes the observable.
But they have a difference in behavior when the source does not emit anything. The first() send an error notification,
while take(1) will not emit anything, but closes the observable.
Last Operator
The last operator emits the last value that meets the condition. If no condition is specified, then it will emit the last
value it receives.
Syntax
1
last<T, D>(predicate?: (value: T, index: number, source: observable<T>) => boolean, defaultValue?:
2
D) :OperatorFunction<T, T | D>
3
Waits for the source to complete before emitting the value
Emits the last value if no predicate is present
Emits the last matching value if the predicate is present
Closes the stream after emitting a value
If the source completes before emitting any matching value, then It raises the error notification.
Example
In the following example, we create an observable using the of operator. The last operator here emits the last value
it receives i.e 5 and then it completes.
1
2 import { Component, VERSION } from "@angular/core";
3 import { timer, interval, of } from "rxjs";
4 import { last } from "rxjs/operators";
5
6 @Component({
7 selector: "my-app",
8 templateUrl: "./app.component.html",
9 styleUrls: ["./app.component.css"]
10 })
11 export class AppComponent {
12 src = of(1, 2, 3, 4, 5).pipe(last());
13
14 id = Date.now();
15
16 constructor() {}
17
18 ngOnInit() {
19 console.log("Component Created " + this.id);
20
21 this.src.subscribe(value => {
22 console.log(value);
23 });
24 }
25 }
26
27 **Console **
28 5
29
Source Code
Emits the last value that matches the predicate
1
2 src = of(1, 2, 3, 4, 5).pipe(last(val => val < 3));
3
4
5 ***Console**
62
7
Source Code
Returns an error as no value matches the condition.
1
2 src = of(1, 2, 3, 4, 5).pipe(last(val => val < 0));
3
4
5 *** Console *****
6 ERROR
7 Error: no elements in sequence
8
9
But with a default value, it will emit the default value if no value matches the condition.
1
2 src = of(1, 2, 3, 4, 5).pipe(last(val => val < 0,0));
3
4
5 ***Console**
6 100
7
The following also results in an error, as the source does not emit any values
1
2 src = of().pipe(last());
3
4 ***Error
5 no elements in sequence
6
The following emits the default value 100
1
2 src = of().pipe(last(val => true, 100));
3
4
5 ***Console
6 100
7
Last Vs TakeLast(1)
The last() (without condition & default value) and takeLast(1) returns the last value they receive from the source
observable.
But they have a difference in behavior when the source does not emit anything. The last() send an error notification,
while takeLast(1) will not emit anything, but closes the observable.
Single
The Single operator emits a single value that meets the condition.
The Single operator waits for the source to complete before emitting the value
Emits a single value that meets the condition
If more than one value satisfies the condition, then it raises an error notification
If no value satisfies the condition, then it emits the value undefined
Raises the error notification, if the source does not emit any value.
Syntax
1
single<T>(predicate?: (value: T, index: number, source: Observable<T>) => boolean):
2
MonoTypeOperatorFunction<T>
3
Where
predicate is the condition
Examples
Emits 3 as it matches the condition.
1
2 src = of(1, 2, 3, 4, 5).pipe(single(val => val == 3));
3
4
5 **Console
63
7
Source Code
Waits for the observable to finish. Hence the following will never emit a value.
1
2 src = interval(1000).pipe(single(val => val == 3));
3
4 **Console*
5
Raises error notification as there are more than one value that satisfies the condition.
1
2 src = of(1, 2, 3, 4, 3).pipe(single(val => val == 3));
3
4
5 **Console**
6 ERROR
7 Sequence contains more than one element
8
9
If the source does not emit any matching values, then the Single operator emits undefined. Note that it does not
emit error notification.
1
2 src = of(1, 2, 3, 4, 3).pipe(single(val => val == 5));
3
4 *Console*
5 undefined
6
Single without any predicate matches all values. Hence the error.
1
2 src = of(1, 2, 3, 4, 3).pipe(single());
3
4 ***Console***
5 ERROR
6 Sequence contains more than one element
7
Source contains single value and Single without predicate. Emits the value
1
2 src = of(1).pipe(single());
3
4 **Console**
51
6
Source is empty, Hence it raises error notification.
1
2 src = of().pipe(single());
3
4
5 **Console***
6 ERROR
7 Error: no elements in sequence
8
Skip, SkipUntil, SkipWhile & SkipLast Operators in Angular
1 Comment / 4 minutes of reading / January 26, 2021
First, Last & Single
Scan & Reduce

The skip operators in Angular skips the values from the source observable based on a condition. The Skip, SkipUntil,
SkipWhile skips the values from the start of the source. The SkipLast Operator skips elements from the end of the
source.

Table of Contents
Skip
Skip Example
SkipWhile
SkipWhile Example
Filter Vs SkipWhile
SkipUntil
SkipUntil Example
SkipLast
SkipLast Example
SkipLast delays the values
Reference
Skip
The skip operator skips the first count number of values from the source observable and returns the rest of the
source as an observable
Syntax
1
2 skip<T>(count: number): MonoTypeOperatorFunction<T>
3
Skip Example
The example below skip(5) ignores the first 5 values & returns the rest of the observable as it is.
1
2 import { Component } from "@angular/core";
3 import { skip } from "rxjs/operators";
4 import { interval, of } from "rxjs";
5
6 @Component({
7 selector: "my-app",
8 template: `
9 <h1>Skip Example</h1>
10
11 <br />
12 <br />
13 `,
14 styleUrls: ["./app.component.css"]
15 })
16 export class AppComponent {
17 ngOnInit() {
18 of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
19 .pipe(
20 skip(5),
21 )
22 .subscribe(val => console.log(val));
23 }
24 }
25
26
27 ** Console **
28 6
29 7
30 8
31 9
32 10
33
Source Code
SkipWhile
The SkipWhile operator skips values from the source observable as long as the specified condition is true. But once
the condition becomes false, it starts to emit the values and continues to do so even if the condition becomes true
again.
Syntax
1
2 skipWhile<T>(predicate: (value: T, index: number) => boolean): MonoTypeOperatorFunction<T>
3
SkipWhile Example
1
2 of( 2, 4, 5, 6, 7, 8, 9, 10)
3 .pipe(
4 skipWhile(val => val % 2==0),
5 )
6 .subscribe(val => console.log(val));
7
8
9 **Console**
10 5
11 6
12 7
13 8
14 9
15 10
16
Filter Vs SkipWhile
The Filter operator and SkipWhile operator uses a predicate to filter out the values.
The SkipWhile skips the values if the predicate is true, While the filter emits the values if the predicate is true.
Once the predicate becomes false, the SkipWhile stops using the predicate and emits all the remaining values.
The filter keeps using the predicate to filter out the remaining values.
Filter Example
1
2 import { Component } from "@angular/core";
3 import { filter } from "rxjs/operators";
4 import { interval, of, timer } from "rxjs";
5
6 @Component({
7 selector: "my-app",
8 template: `
9 <h1>Filter Example</h1>
10 `,
11 styleUrls: ["./app.component.css"]
12 })
13 export class AppComponent {
14 ngOnInit() {
15 of(2, 4, 5, 6, 7, 8, 9, 10)
16 .pipe(
17 filter(val => {
18 return val %2==0;
19 }),
20 )
21 .subscribe(val => console.log(val));
22 }
23 }
24
25
26 ***Console***
27 2
28 4
29 6
30 8
31 10
32
SkipUntil
The SkipUntil operator skips the values from the source observable as long as the second observable does not emit
any value. But once the second observable emits a value, it starts to emit the values and continues to do so as long
as the source emits values.
It is very similar to SkipWhile except that the condition is provided by another observable.
Syntax
1
2 skipUntil<T>(notifier: Observable<any>): MonoTypeOperatorFunction<T>
3
SkipUntil Example
The interval creates an observable, which emits a value for every 1000 ms. The SkipUntil operator uses the
timer(6000) observable, which emits a value after 6000ms. Hence the SkipUntil skips the first 5 values (0 to 4) and
starts to emit the values from 5
1
2 interval(1000)
3 .pipe(
4 skipUntil(timer(6000)),
5 )
6 .subscribe(val => console.log(val));
7
8 ***Console **
9 5
10 6
11 7
12 8
13 ....
14
Source Code
SkipLast
The SkipLast operator skips the last count number of values from the source observable and returns the rest of the
source as an observable.
It is exactly opposite of skip(count), which skips the first count number of values
Syntax
1
2 skipLast<T>(count: number): MonoTypeOperatorFunction<T>
3
SkipLast Example
In the following example, the skiplast(5) will skip the last 5 values (i.e 6 to 10)
1
2 of(1,2,3,4,5,6,7,8,9,10)
3 .pipe(
4 skipLast(5)
5 )
6 .subscribe(val => console.log(val));
7
8 **Console*
9 1
10 2
11 3
12 4
13 5
14
Source Code
SkipLast delays the values
SkipLast(count) waits until it receives the count number of values from the source, before it starts emitting the
values.
In the above example, the skipLast does not emit any values till the values 5. When it receives the value 6, it emits
the value 1. You can see it by using the tap operator.
1
2 of(1,2,3,4,5,6,7,8,9,10)
3 .pipe(
4 tap(val => {
5 console.log("tap " + val);
6 }),
7 skipLast(5)
8 )
9 .subscribe(val => console.log(val));
10
11
12 **Console**
13 tap 1
14 tap 2
15 tap 3
16 tap 4
17 tap 5
18 tap 6
19 1
20 tap 7
21 2
22 tap 8
23 3
24 tap 9
25 4
26 tap 10
27 5
28
The Scan & Reduce operators in Angular
Leave a Comment / 5 minutes of reading / January 26, 2021
Skip, SkipUntil, SkipWhile & SkipLast
Debounce & DebounceTime

The Scan & Reduce Operators in Angular applies an accumulator function on the values of the source observable.
The Scan Operator returns all intermediate results of the accumulation, while Reduce only emits the last result. Both
also use an optional seed value as the initial value.
Table of Contents
Scan in Angular
Scan Example
Reduce in Angular
Reduce Example
References
Scan in Angular
The scan operator applies an accumulator function over the values emitted by the source Observableble sequentially
and emits each value.
Syntax
1
2 scan<T, R>(accumulator: (acc: R, value: T, index: number) => R, seed?: T | R): OperatorFunction<T, R>
3
Where
accumulator is the function, that is called on each source value
seed is the initial accumulation value (optional)
The accumulator function gets three argument.
acc is the accumulator variable where the values are accumulated.
value comes from the source observable,
index of the value.
The initial value for the acc comes from the seed.
When the first value arrives from the source, the scan operator invokes the accumulator function on these two
variables and emits the result.
When the second value arrives from the source, the result of the previous step becomes the input ( acc ). The scan
emits a new result, which then becomes the input for the third emission.
This cycle continues till the stream completes.
Scan Example
In the example below (acc, value) => acc + value is the accumulator function. Seed is 0.
1
2 import { Component } from "@angular/core";
3 import { map, scan } from "rxjs/operators";
4 import { interval, of } from "rxjs";
5
6 @Component({
7 selector: "my-app",
8 template: `
9 <h1>Scan Operator Example</h1>
10 `,
11 styleUrls: ["./app.component.css"]
12 })
13 export class AppComponent {
14 reTryCount = 0;
15
16 ngOnInit() {
17 of(1, 2, 3, 4, 5)
18 .pipe(scan((acc, value) => acc + value, 0))
19 .subscribe(
20 val => console.log(val),
21 e => console.log(e),
22 () => console.log("Complete")
23 );
24 }
25 }
26
27
28 ***Console***
29
30 1
31 3
32 6
33 10
34 15
35 Complete
36
Source Code
The value for acc starts with the seed value i.e. 0. The variable value gets the value 1, which is the first value emitted
by the source. The scan operator runs the accumulator function (acc + value = 1) and emits the result.
The result of the previous accumulator function becomes the input (acc) of the next scan. It is added to the next
value (i. e. 2) emitted from the source and the result becomes 3.
This will continue until we reach the end of sequence
In the following code, we change the seed to 10. Now the accumulator starts with 10 instead of 0.
1
2 of(1, 2, 3, 4, 5)
3 .pipe(scan((acc, value) => acc + value, 10))
4 .subscribe(
5 val => console.log(val),
6 e => console.log(e),
7 () => console.log("Complete")
8 );
9
10 *** Result ***
11 11
12 13
13 16
14 20
15 25
16 Complete
17
18
Combining as Arrays
1
2 of(1, 2, 3, 4, 5)
3 .pipe(scan((acc, value) => [...acc, value], []))
4 .subscribe(
5 val => console.log(val),
6 e => console.log(e),
7 () => console.log("Complete")
8 );
9
10 *** Console ***
11 [1]
12 [1, 2]
13 [1, 2, 3]
14 [1, 2, 3, 4]
15 [1, 2, 3, 4, 5]
16
Source Code
Tracking Button Clicks
1
2 import { Component, ElementRef, ViewChild } from "@angular/core";
3 import { map, scan } from "rxjs/operators";
4 import { fromEvent, interval, of, Subscription } from "rxjs";
5
6 @Component({
7 selector: "my-app",
8 template: `
9 <h1>Scan Operator Example</h1>
10
11 <button #btn>Button</button>
12 `,
13 styleUrls: ["./app.component.css"]
14 })
15 export class AppComponent {
16 @ViewChild("btn", { static: true }) button: ElementRef;
17 sub: Subscription;
18
19 ngAfterViewInit() {
20 this.sub = fromEvent(this.button.nativeElement, "click")
21 .pipe(scan((acc, value) => acc + 1, 0))
22 .subscribe(val => console.log("You clicked " + val + " times"));
23 }
24
25 ngOnDestroy() {
26 this.sub.unsubscribe();
27 }
28 }
29
30
Source Code
Reduce in Angular
The Reduce operator applies an accumulator function over the values emitted by the source Observation
sequentially and returns the accumulated result when the source completes.
The Reduce operator behaves exactly like the scan operator, except for the following differences
It does not return the intermediate results.
It returns only after the source completes.
Reduce Example
The following example is similar to the scan example above. The only difference is that you will not see the
intermediate results i.e. 1, 3, 6 10.
1
2 ngOnInit() {
3 of(1, 2, 3, 4, 5)
4 .pipe(reduce((acc, value) => acc + value, 0))
5 .subscribe(
6 val => console.log(val),
7 e => console.log(e),
8 () => console.log("Complete")
9 );
10 }
11
12
13 ** Console **
14
15 15
16 Complete
17
Source Code
Combining as Arrays
1
2 ngOnInit() {
3 of(1, 2, 3, 4, 5)
4 .pipe(reduce((acc, value) => [...acc, value], []))
5 .subscribe(
6 val => console.log(val),
7 e => console.log(e),
8 () => console.log("Complete")
9 );
10 }
11
12 ** Console ***
13 [1, 2, 3, 4, 5]
14 Complete
15
Source Code
Tracking Button Clicks
The Reduce operator emits only if the observable completes. Hence in the Tracking button click example, just
replacing the scan with the reduce will not work.
In the following example, we create a new observable using the Subject and emit the click event using the event
binding. This allows us to raise the complete notification.
1
2 import { Component, ElementRef, ViewChild } from "@angular/core";
3 import { map, reduce, scan } from "rxjs/operators";
4 import { fromEvent, interval, of, Subject, Subscription } from "rxjs";
5
6 @Component({
7 selector: "my-app",
8 template: `
9 <h1>Reduce Operator Example</h1>
10
11 <button (click)="clickMe($event)">Click Me</button>
12 <br />
13 <br />
14 <br />
15 <button (click)="startCounting($event)">Sart</button>
16
17 <button (click)="stopCounting()">Stop</button>
18 `,
19 styleUrls: ["./app.component.css"]
20 })
21 export class AppComponent {
22 clickStream: Subject<Event>;
23 sub: Subscription;
24
25 ngOnInit() {}
26
27 clickMe(event: Event) {
28 console.log("Clicked");
29 if (this.clickStream) this.clickStream.next(event);
30 }
31
32 startCounting(event: Event) {
33 this.clickStream = new Subject<Event>();
34 this.sub = this.clickStream
35 .asObservable()
36 .pipe(reduce((acc, value) => acc + 1, 0))
37 .subscribe(val => console.log("You clicked " + val + " times"));
38 }
39
40 stopCounting() {
41 this.clickStream.complete();
42 }
43
44 ngOnDestroy() {}
45 }
46
47
DebounceTime & Debounce in Angular
Leave a Comment / 3 minutes of reading / January 26, 2021
Scan & Reduce
Delay & DelayWhen

DebounceTime & Debounce are the Angular RxJs Operators. Both emit values from the source observable, only after
a certain amount of time has elapsed since the last value. Both emit only the latest value and discard any
intermediate values. In this tutorial, we will learn how to use both DebounceTime & Debounce with examples.

Table of Contents
Use Case of Debounce Operators
DebounceTime
How it works
DebounceTime Example
Sending HTTP GET Request
Debounce
Debounce Example
Reference
Use Case of Debounce Operators
The typeahead/autocomplete fields are one of the most common use cases for Debounce Operators.
As the user types in the typeahead field, we need to listen to it and send an HTTP request to the back end to get a list
of possible values. If we send HTTP requests for every keystroke, we end up making numerous unneeded calls to the
server.
By using the Debounce Operators, we wait until the user pauses typing before sending an HTTP Request. This will
eliminates unnecessary HTTP requests.
DebounceTime
The Debouncetime emits the last received value from the source observable after a specified amount of time has
elapsed without any other value appearing on the source Observable
Syntax
1
2 debounceTime<T>(dueTime: number, scheduler: SchedulerLike = async): MonoTypeOperatorFunction<T>
3
Where dueTime The timeout duration in milliseconds.
How it works
First, we assign a timeout duration (dueTime) to the Debouncetime operator.
The Debouncetime operator starts counting time after it receives a value.
If the source observable emits a value before the timeout duration, then counting is reset to zero & started again.
When the timeout duration elapses the operator emits the last value and the counting stops.
Counting starts again when the operators receive another value.
DebounceTime Example
The following DebounceTime example shows how to use the operator to listen for input field changes
1
2 import { Component, VERSION } from "@angular/core";
3 import { FormControl, FormGroup } from "@angular/forms";
4 import { Observable, Subscription } from "rxjs";
5 import { debounceTime } from "rxjs/operators";
6
7 @Component({
8 selector: "my-app",
9 template: `
10 <form [formGroup]="mform">Name: <input formControlName="name" /></form>
11 `,
12 styleUrls: ["./app.component.css"]
13 })
14 export class AppComponent {
15
16 mform: FormGroup = new FormGroup({
17 name: new FormControl()
18 });
19
20 obs:Subscription;
21
22 ngOnInit() {
23 this.obs=this.mform.valueChanges
24 .pipe(debounceTime(500))
25 .subscribe(data => console.log(data));
26 }
27
28 ngOnDestroy() {
29 this.obs.unsubscribe();
30 }
31 }
32
Souce Code
Sending HTTP GET Request
The following example shows how you can send an HTTP GET Request using switchMap & debounceTime.
1
2 ngOnInit() {
3 this.obs=this.mform.valueChanges
4 .pipe(
5 debounceTime(500),
6 switchMap(id => {
7
8 console.log(id)
9 return this.http.get(url)
10
11 })
12 )
13 .subscribe(data => console.log(data));
14 }
15
Debounce
The Debounce operator is similar to the DebounceTime operator, but another observable will provide the time span.
By Using the Debounce, we can set the time span dynamically.
Debounce Example
The following example works the same as the previous example. Instead of using the hardcoded time span, we
create a new observable using the interval operator.
1
2 import { Component, VERSION } from "@angular/core";
3 import { FormControl, FormGroup } from "@angular/forms";
4 import { debounce } from "rxjs/operators";
5 import { interval, Subscription } from "rxjs";
6
7 @Component({
8 selector: "my-app",
9 template: `
10 <form [formGroup]="mform">Name: <input formControlName="name" /></form>
11 `,
12 styleUrls: ["./app.component.css"]
13 })
14 export class AppComponent {
15 mform: FormGroup = new FormGroup({
16 name: new FormControl()
17 });
18
19 obs:Subscription
20
21 ngOnInit() {
22 this.obs=this.mform.valueChanges
23 .pipe(debounce(() => interval(500)))
24 .subscribe(data => console.log(data));
25 }
26
27 ngOnDestroy() {
28 this.obs.unsubscribe()
29 }
30
31 }
32
33
Source Code
You can also customize the delay. In the following example, we increase the delay by 100ms after every keystroke.
1
2
delay = 500;
3
4
obs: Subscription;
5
6
ngOnInit() {
7
this.obs = this.mform.valueChanges
8
.pipe(
9
debounce(() => {
10
this.delay = this.delay + 100;
11
console.log(this.delay);
12
return interval(this.delay);
13
})
14
)
15
.subscribe(data => console.log(data));
16
}
17
Delay & DelayWhen in Angular
Leave a Comment / 3 minutes of reading / January 26, 2021
DebounceTime & Debounce
ThrowError

Delay & DelayWhen Operators in Angular delays the emission of values from the source observable. The Delay
operator delays by a given timeout or until a given Date. The DelayWhen delays until it receives a notification from
another observable.
Table of Contents
Delay
Delay Example
Delay Each item
Passing Date to Delay Operator
DelayWhen
DelayWhen Example
References
Delay
Delays the emission of items from the source Observable by a given timeout or until a given Date.
Syntax
1
2 delay<T>(delay: number | Date, scheduler: SchedulerLike = async): MonoTypeOperatorFunction<T>
3
Where
delay is the delay in milliseconds or a Date until which the emission of the source items are delayed
Note that delay delays the entire observable and not the individual items.
Delay Example
In the following example, we add a delay of 1000ms. After 1000ms all the values appear instantly.
1
2 import { Component, VERSION } from "@angular/core";
3 import { of } from "rxjs";
4 import { delay, map, tap } from "rxjs/operators";
5
6 @Component({
7 selector: "my-app",
8 template: `
9 <h1>Delay & DelayWhen Example</h1>
10 `,
11 styleUrls: ["./app.component.css"]
12 })
13 export class AppComponent {
14 ngOnInit() {
15 of(1, 2, 3, 4, 5)
16 .pipe(
17 tap(val => console.log("Before " + val)),
18 delay(1000)
19 )
20 .subscribe(
21 val => console.log(val),
22 e => console.log(e),
23 () => console.log("Complete")
24 );
25 }
26 }
27
28
29 Before 1
30 Before 2
31 Before 3
32 Before 4
33 Before 5
34
35 1
36 //Appears after a delay of 1000ms
37 2
38 3
39 4
40 5
41 Complete
42
Source Code
Delay Each item
The following code uses concatMap with delay operator to add delay between each emission.
1
2
3 of(1, 2, 3, 4, 5)
4 .pipe(
5 tap(val => console.log("Before " + val)),
6 concatMap(item => of(item).pipe(delay(1000)))
7 )
8 .subscribe(
9 val => console.log(val),
10 e => console.log(e),
11 () => console.log("Complete")
12 );
13
14
15 *** Console ****
16
17 Before 1
18 Before 2
19 Before 3
20 Before 4
21 Before 5
22
23 1
24 2
25 3
26 4
27 5
28 Complete
29
Source Code
Passing Date to Delay Operator
Instead of delay in milliseconds, we can also pass the date. Operator time shifts the start of the Observable
execution until the given date occurs.
In the following example, we add a 5 second to the current date and pass it to the delay operator.
1
2 import { Component, VERSION } from "@angular/core";
3 import { of } from "rxjs";
4 import { delay, tap } from "rxjs/operators";
5
6 @Component({
7 selector: "my-app",
8 template: `
9 <h1>Delay & DelayWhen Example</h1>
10 `,
11 styleUrls: ["./app.component.css"]
12 })
13 export class AppComponent {
14 dt = new Date();
15
16 ngOnInit() {
17 console.log(this.dt);
18
19 this.dt.setSeconds(this.dt.getSeconds() + 5);
20 console.log(this.dt);
21
22 of(1, 2, 3, 4, 5)
23 .pipe(
24 tap(val => console.log("Tap " + val)),
25 delay(this.dt)
26 )
27 .subscribe(
28 val => console.log(val),
29 e => console.log(e),
30 () => console.log("Complete")
31 );
32 }
33 }
34
35
36
Source Code
DelayWhen
Delays the emission of items from the source observable by a given time span determined by the emissions of
another observable.
DelayWhen Example
The DelayWhen triggers when the timer observable emits an value after 1000 ms.
1
2 of(1, 2, 3, 4, 5)
3 .pipe(
4 tap(val => console.log("Before " + val)),
5 delayWhen(() => timer(1000))
6 )
7 .subscribe(
8 val => console.log(val),
9 e => console.log(e),
10 () => console.log("Complete")
11 );
12
13
14 *** Console ****
15 Before 1
16 Before 2
17 Before 3
18 Before 4
19 Before 5
20 1
21 2
22 3
23 4
24 5
25 Complete
26
In the following example, we create notification observable using Subject and use it in the DelayWhen Operator. We
emit the notification when the users click on a button. The DelayWhen waits until the notification before emitting
the values
1
2
import { Component, VERSION } from "@angular/core";
3
import { interval, of, Subject, timer } from "rxjs";
4
import { concatMap, delay, delayWhen, map, tap } from "rxjs/operators";
5
6
@Component({
7
selector: "my-app",
8
template: `
9
<h1>Delay & DelayWhen Example</h1>
10
11
<button (click)="emit()">Emit</button>
12
`,
13
styleUrls: ["./app.component.css"]
14
})
15
export class AppComponent {
16
click$ = new Subject<Event>();
17
18
ngOnInit() {
19
of(1, 2, 3, 4, 5)
20
.pipe(
21
tap(val => console.log("Before " + val)),
22
delayWhen(() => this.click$.asObservable())
23
)
24
.subscribe(
25
val => console.log(val),
26
e => console.log(e),
27
() => console.log("Complete")
28
);
29
}
30
31
emit() {
32
this.click$.next();
33
}
34
35
}
36
37
Using ThrowError in Angular Observable
Leave a Comment / 6 minutes of reading / January 26, 2021
Delay & DelayWhen
CatchError

Angular ThrowError operator returns an observable, which on subscription immediately errors out. It does not emit
any results.

Table of Contents
ThrowError
Throw Error Vs ThrowError
Throw Error Example
ThrowError
Using ThrowError
Using with catchError
Using it with MergeMap
References
ThrowError
ThrowError creates a new observable. Hence we must subscribe to it. The following example creates an ThrowError
observable and then subscribes to it.
1
2 import { Component, VERSION } from "@angular/core";
3 import { Observable, of, from, throwError } from "rxjs";
4 import { map, catchError } from "rxjs/operators";
5
6 @Component({
7 selector: "my-app",
8 templateUrl: "./app.component.html",
9 styleUrls: ["./app.component.css"]
10 })
11 export class AppComponent {
12 name = "Angular " + VERSION.major;
13
14 obs = throwError("Error From ThrowError observable");
15
16 ngOnInit() {
17 this.obs.subscribe(
18 el => {
19 console.log("Value Received :" + el);
20 },
21 err => {
22 console.log("Error caught at Subscriber :" + err);
23 },
24 () => console.log("Processing Complete")
25 );
26 }
27 }
28
29
30
31 ****Console Window
32
33 Error caught at Subscriber: Error From ThrowError observable
34
Source Code
First, we create an observable using throwError. The first argument to the throwError is the error object. This error
object is passed to the consumers when it raises the error notification.
1
2 obs = throwError("Error From ThrowError observable")
3
We, subscribe to it in the ngOnInit method.
1
2 this.obs.subscribe(
3
4
The observable immediately raises the error notification and completes. The error callback is invoked and we will see
the error message in the console window.
1
2 err => {
3 console.log("Error caught at Subscriber :" + err);
4 },
5
6
Throw Error Vs ThrowError
It is very easy confuse between the Throw Error With ThrowError.
Throw Error throws an error. It is a JavaScript construct and is not part of the RxJs. We need to use the try/catch
block to catch the errors thrown from the Throw Error. The RxJS uses the try/catch block to catch any errors thrown
from the observables. And when they catch one, they emit an error notification (raises the error callback), and then
the observable stops.
ThrowError does not throw errors like throw Error. It returns a new observable, which emit an error notification
(raises the error callback), and then stops.
Throw Error Example
1
2 import { Component, VERSION } from "@angular/core";
3 import { Observable, of, from, throwError } from "rxjs";
4 import { map, catchError } from "rxjs/operators";
5
6 @Component({
7 selector: "my-app",
8 templateUrl: "./app.component.html",
9 styleUrls: ["./app.component.css"]
10 })
11 export class AppComponent {
12
13
14 srcArray = from([1, 2, "A", 4]);
15
16 obs = this.srcArray.pipe(
17 map(val => {
18 let result = (val as number) * 2;
19 if (Number.isNaN(result)) {
20 console.log("Error in the observable");
21 throw Error("Not a Number");
22 }
23 return result;
24 })
25 );
26
27 ngOnInit() {
28 this.obs.subscribe(
29 el => {
30 console.log("Value Received :" + el);
31 },
32 err => {
33 console.log("Error caught at Subscriber :" + err);
34 },
35 () => console.log("Processing Complete.")
36 );
37 }
38 }
39
40
41 ***Console ****
42
43 Value Received :2
44 Value Received :4
45 Error in the observable
46 Error caught at Subscriber :Error: Not a Number
47
Source Code
The observable emits values 2 & 4.
When map operators receive the value A it uses throw Error to throw an error. The observable catches this error and
raises the error notification and terminates.
The last value 8 is never emitted.
ThrowError
Now, let us replace the throw Error with return throwError
1
2 import { Component, VERSION } from "@angular/core";
3 import { Observable, of, from, throwError } from "rxjs";
4 import { map, catchError } from "rxjs/operators";
5
6 @Component({
7 selector: "my-app",
8 templateUrl: "./app.component.html",
9 styleUrls: ["./app.component.css"]
10 })
11 export class AppComponent {
12 name = "Angular " + VERSION.major;
13
14 srcArray = from([1, 2, "A", 4]);
15
16 obs = this.srcArray.pipe(
17 map(val => {
18 let result = (val as number) * 2;
19 if (Number.isNaN(result)) {
20 console.log("Error in the observable");
21 return throwError("Not a Number");
22 }
23 return result;
24 })
25 );
26
27 ngOnInit() {
28 this.obs.subscribe(
29 (el: any) => {
30 console.log("Value Received :" + el);
31 },
32 err => {
33 console.log("Error caught at Subscriber :" + err);
34 },
35 () => console.log("Processing Complete.")
36 );
37 }
38 }
39
40
41 ****Console ********
42 Value Received :2
43 Value Received :4
44 Error in the observable
45 Value Received :[object Object]
46 Value Received :8
47 Processing Complete
48
49
Source Code
The observable emits values 2 & 4.
When the map operator receive the value A it returns throwError. Remember throwError returns an observable. It
will raise the error notification, only if you subscribe to it.
The map operator does not subscribe to the observable. It just returns it to the subscriber.
Hence the subscriber receives the throwError observable as value. Hence you see [object Object] in the console.
Since there is no error raised, the observable continues and emits the next value 8 and then completes.
Using ThrowError
The throwError needs to be subscribed for it to emit error notification. We can use it to compose with other
Observables such as mergeMap, switchMap, catchError etc.
Using with catchError
The following example, shows how to use ThrowError with CatchError
1
2 import { Component, OnInit } from "@angular/core";
3 import { throwError, from } from "rxjs";
4 import { map, catchError } from "rxjs/operators";
5
6 @Component({
7 selector: "my-app",
8 templateUrl: "./app.component.html",
9 styleUrls: ["./app.component.css"]
10 })
11 export class AppComponent {
12 srcArray = from([1, 2, "A", 4]);
13
14 obs = this.srcArray.pipe(
15 map(val => {
16 let result = (val as number) * 2;
17 if (Number.isNaN(result)) {
18 console.log("Errors Occurred in Stream");
19 throw new Error("Result is NaN");
20 }
21 return result;
22 }),
23 catchError(error => {
24 console.log("Caught in CatchError. Throwing error");
25 return throwError(error);
26 })
27 );
28
29 ngOnInit() {
30 this.obs.subscribe(
31 el => {
32 console.log("Value Received " + el);
33 },
34 err => {
35 console.log("Error caught at Subscriber " + err);
36 },
37 () => console.log("Processing Complete.")
38 );
39 }
40 }
41
42
43 ******* CONSOLE *******
44 Value Received 2
45 Value Received 4
46 Errors Occurred in Stream
47 Caught in CatchError. Throwing error
48 Error caught at Subscriber Error: Result is NaN
49
50
Source Code
The code throws the error using throw error in map operator.
CatchError will catch this error. We use the CatchError to handle the errors thrown by the Angular Observable. Once
we handle the error, we must return an observable. We can either return a replacement observable or return an
error. The observable returned from CatchError is immediately subscribed.
Hence we can use the throwError here, which is immediately subscribed , which in turn emits an error notification
1
2 catchError(error => {
3 console.log("Caught in CatchError. Throwing error");
4 return throwError(error);
5 })
6
7
Using it with MergeMap
The Angular MergeMap maps each value from the source observable into an inner observable, subscribes to it, and
then starts emitting the values from it.
In the following example, we use throwError to return a observable, when we receive the value 3.
The MergeMap subscribes to this new observable and raises the error notification and stops.
1
2 import { Component, OnInit } from "@angular/core";
3 import { throwError, of } from "rxjs";
4 import { map, mergeMap, catchError } from "rxjs/operators";
5
6 @Component({
7 selector: "my-app",
8 templateUrl: "./app.component.html",
9 styleUrls: ["./app.component.css"]
10 })
11 export class AppComponent {
12 srcObservable = of(1, 2, 3, 4);
13 innerObservable = of("A", "B");
14
15 obs = this.srcObservable.pipe(
16 mergeMap(val => {
17 console.log("Source value " + val);
18 console.log("starting new observable");
19
20 if (val == 3) return throwError("Error in observable");
21
22
23 return this.innerObservable;
24 })
25 );
26
27 ngOnInit() {
28 this.obs.subscribe(
29 el => {
30 console.log("Value Received " + el);
31 },
32 err => {
33 console.log("Error caught at Subscriber " + err);
34 },
35 () => console.log("Processing Complete.")
36 );
37 }
38 }
39
40
41 ***Console ****
42 Source value 1
43 starting new observable
44 Value Received A
45 Value Received B
46 Source value 2
47 starting new observable
48 Value Received A
49 Value Received B
50 Source value 3
51 starting new observable
52 Error caught at Subscriber Error in observable
53
Source Code
Using Catcherror Operator in Angular Observable
Leave a Comment / 6 minutes of reading / January 26, 2021
ThrowError
ReTry & ReTryWhen

Angular CatchError is an RxJs Operator. We can use it to handle the errors thrown by the Angular Observable. Like all
other RxJs operators, the CatchError also takes an observable as input and returns an observable (or throws an
error). We can use CatchError to provide a replacement observable or throw a user-defined error. Let us learn all
these in this tutorial.

Catch operator was renamed as catchError in RxJs 5.5, Hence if you are using Angular 5 or prior version then use
catch instead of catchError.
Table of Contents
Handling Errors in Observable
Using Error Callback of Subscribe method
Catch errors in the observable stream
Using CatchError Operator
Syntax
Returning a new observable
Throws a new Error
Retrying
References
Handling Errors in Observable
We can handle the errors at two places.
Using the error callback of the subscribe method
Catch errors in the observable stream
Using Error Callback of Subscribe method
We subscribe to an Observable by using the subscribe method. The subscribe method accepts three callback
methods as arguments. They are the next value, error, or complete event. We use the error callback to catch &
handle the errors.
For Example, consider the following code. The obs observable multiplies the values (srcArray) by 2 using
the map operator. If the result is NaN, then we throw an error using throw new Error("Result is NaN").

BEST ANGULAR BOOKS


The Top 8 Best Angular Books, which helps you to get started with Angular
1
2 srcArray = from([1, 2, 'A', 4]);
3
4 obs = this.srcArray
5 .pipe(
6 map(val => {
7 let result = val as number * 2;
8 if (Number.isNaN(result)) {
9 console.log('Errors Occurred in Stream')
10 throw new Error("Result is NaN")
11 }
12 return result
13 }),
14 );
15
16 ngOnInit() {
17
18 this.obs.subscribe(
19 el => {
20 console.log('Value Received ' + el)
21 },
22 err => {
23 console.log("Error caught at Subscriber " + err)
24 },
25 () => console.log("Processing Complete.")
26 )
27 }
28
29
30 **** Output *****
31 Value Received 2
32 Value Received 4
33 Errors Occurred in Stream
34 Error Caught at subscriber Error: Result is NaN
35
Source Code
We subscribe and start to receive the values from the obs observable in the ngOnInit method. When the observable
stream throws an error, it invokes the error callback. In the error callback, we decide what to do with the error.
Note that once the observable errors out it will not emit any values neither it calls the complete callback. Our
subscription method will never receive the final value of 8.
Catch errors in the observable stream
Another option to catch errors is to use the CatchError Operator. The CatchError Operators catches the error in the
observable stream as and when the error happens. This allows us to retry the failed observable or use a replacement
observable.
Using CatchError Operator
To use CatchError operator, we need to import it from the rxjs/operators as shown below
1
2 import { catchError } from 'rxjs/operators'
3
Syntax
The catchError is a pipeable operator. We can use it in a Pipe method similar to the other operators like Map, etc.
The catchError operator gets two argument.
The first argument is err, which is the error object that was caught.
The second argument is caught, which is the source observable. We can return it back effectively retrying the
observable.
The catchError must return a new observable or it can throw an error.
Returning a new observable
The following examples shows the use of catchError operator.
1
2 srcArray = from([1, 2, 'A', 4]);
3
4 obs = this.srcArray
5 .pipe(
6 map(val => {
7 let result = val as number * 2;
8 if (Number.isNaN(result)) {
9 console.log('Errors Occurred in Stream')
10 throw new Error("Result is NaN")
11 }
12 return result
13 }),
14 catchError(error => {
15 console.log('Caught in CatchError. Returning 0')
16 return of(0); //return from(['A','B','C'])
17 })
18 );
19
20
21 //Output
22 Value Received 2
23 Value Received 4
24 Errors Occurred in Stream
25 Caught in CatchError. Returning 0
26 Value Received 0
27 Observable Completed
28
Source Code
In the code above, the map emits the values 2 & 4, which is input to the catchError. Since there are no
errors, catchError forwards it to the output. Hence the subscribers receive values 2 & 4.
The catchError comes into play, when the map operator throws an error. The catchError handle the error and must
return a new observable (or throw an error). In the example above we return a new observable i.e. of(0). You can
also emit any observable for example return from(['A','B','C']) etc
You can also return the original observable. Just use the return this.obs; instead of return of(0);. But beware, It will
result in an infinite loop.
The new observable is automatically subscribed and the subscriber gets the value 0. The new observable now
finishes and emits the complete event.
Since the original observable ended in a error, it will never emit the the value 8.
Throws a new Error
catchError can also throw an error. In the following example, we use the throw new Error(error) to throw a
JavaScript error. This error will propagate to the subscriber as shown in the example below.
1
2 obs = this.srcArray
3 .pipe(
4 map(val => {
5 let result = val as number * 2;
6 if (Number.isNaN(result)) {
7 console.log('Errors Occurred in Stream')
8 throw new Error("Result is NaN")
9 }
10 return result
11 }),
12 catchError(error => {
13 console.log('Caught in CatchError. Throwing error')
14 throw new Error(error)
15 })
16 );
17
18
19 //OUTPUT
20 Value Received 2
21 Value Received 4
22 Errors Occurred in Stream
23 Caught in CatchError. Throwing error
24 Error caught at Subscriber Error: Error: Result is NaN
25
Source Code
We can also make use of throwError to return an observable. Remember that the throwError does not throw an
error like throw new Error but returns an observable, which emits an error immediately.
1
2 obs = this.srcArray
3 .pipe(
4 map(val => {
5 let result = val as number * 2;
6 if (Number.isNaN(result)) {
7 console.log('Errors Occurred in Stream')
8 throw new Error("Result is NaN")
9 }
10 return result
11 }),
12 catchError(error => {
13 console.log('Caught in CatchError. Throwing error')
14 return throwError(error);
15 })
16 );
17
18 //OUTPUT
19 Value Received 2
20 Value Received 4
21 Errors Occurred in Stream
22 Caught in CatchError. Throwing error
23 Error caught at Subscriber Error: Result is NaN
24
Source code
Retrying
You can also retry the observable using the Retry operator.
1
2 obs = this.srcArray
3 .pipe(
4 map(val => {
5 let result = val as number * 2;
6 if (Number.isNaN(result)) {
7 console.log('Errors Occurred in Stream')
8 throw new Error("Result is NaN")
9 }
10 return result
11 }),
12 retry(2),
13 catchError((error,src) => {
14 console.log('Caught in CatchError. Throwing error')
15 throw new Error(error)
16 })
17 );
18
19
20 //Output
21 Value Received 2
22 Value Received 4
23 Errors Occurred in Stream
24 Value Received 2
25 Value Received 4
26 Errors Occurred in Stream
27 Value Received 2
28 Value Received 4
29 Errors Occurred in Stream
30 Caught in CatchError. Throwing error
31 Error caught at Subscriber Error: Error: Result is NaN
32
Source Code
The catchError gets the source observable as the second argument. If we return it, it will get subscribed again
effectively retrying the observable.
Ensure that you keep track of no of tries so that you can stop the observable after a few failed attempts. Otherwise,
you may run into an infinite loop if the observable always emits an error.
1
2 obs = this.srcArray
3 .pipe(
4 map(val => {
5 let result = val as number * 2;
6 if (Number.isNaN(result)) {
7 console.log('Errors Occurred in Stream')
8 throw new Error("Result is NaN")
9 }
10 return result
11 }),
12 catchError((error,src) => {
13 console.log('Caught in CatchError. Throwing error')
14 this.count++;
15 if (this.count < 2) {
16 return src;
17 } else {
18 throw new Error(error)
19 }
20 })
21 );
22

ReTry & ReTryWhen Operators help us to retry a failed observable in Angular. These operators are useful in Error
handling. They both resubscribe to the source observable when they receive onError() notification.

Table of Contents
ReTry
ReTry Example
ReTryWhen
How it works
ReTryWhen Example
Adding a Delay
Notifier observable
Limiting Retry Attempts
References
ReTry
The ReTry Angule RxJs operator retries a failed source observable count number of times. If the count is not
provided then it tries indefinitely
Syntax
1
2 retry<T>(count: number = -1): MonoTypeOperatorFunction<T>
3
Mirrors the source observable, if there are no errors.
If the source observable calls error notification, it does not propagate it. But re subscribes to the source again for a
maximum of count times.
The Retry operator retries the operation immediately
ReTry Example
In the example below, map operator throws an error if the source emits a value greater than 3.
The ReTry(2) retries the operation twice before erroring out.
1
2 import { Component } from "@angular/core";
3 import { map, retry, tap } from "rxjs/operators";
4 import { interval } from "rxjs";
5
6 @Component({
7 selector: "my-app",
8 template: `
9 <h1>Retry And ReTryWhen Example</h1>
10 `,
11 styleUrls: ["./app.component.css"]
12 })
13 export class AppComponent {
14 ngOnInit() {
15 interval(1000)
16 .pipe(
17 map(val => {
18 if (val > 2) throw new Error("Invalid Value");
19 return val;
20 }),
21 retry(2)
22 )
23 .subscribe(
24 val => console.log(val),
25 err => console.log(err),
26 () => console.log("Complete")
27 );
28 }
29 }
30
31
Source Code
Retry without any argument, will retry indefinitely
1
2 interval(1000)
3 .pipe(
4 map(val => {
5 if (val > 2) throw new Error("Invalid Value");
6 return val;
7 }),
8 retry()
9 )
10 .subscribe(val => console.log(val));
11
Retry(0) never retries.
1
2 interval(1000)
3 .pipe(
4 map(val => {
5 if (val > 2) throw new Error("Invalid Value");
6 return val;
7 }),
8 retry(0)
9 )
10 .subscribe(val => console.log(val));
11
ReTryWhen
The RetryWhen Angule RxJs operator retries the failed Observable every time a Notification Observable emits
the next value.
Syntax
1
2 retryWhen<T>(notifier: (errors: Observable<any>) => Observable<any>): MonoTypeOperatorFunction<T>
3
Where notifier is the callback, which returns the Notification Observable
How it works
We register the notifier callback with the ReTryWhen Operator.
The notifier gets the errors observable as the argument, which emits whenever the source observable errors
We return the notifier observable, which we build using the errors observable.
The ReTryWhen subscribes to this notifier observable and how it behaves depends on the value emitted by
the notifier observable
If the notifier emits a value, then ReTryWhen re subscribes the source observable.
In case of notifier emitting an error, then ReTryWhen also emits an error.
If the notifier completes, then ReTryWhen does nothing.
ReTryWhen Example
In the following example, map operator throws an error if the val > 2.
The errors are caught by retryWhen. It gets the error observable as its input. We use the pipe operator to add
a tap to print the Retrying message on the console.
This code runs indefinitely as the source will always errors out and there is nothing to stop retryWhen
1
2 import { Component } from "@angular/core";
3 import { map, retryWhen, tap, take } from "rxjs/operators";
4 import { interval, Observable, observable, of, throwError, timer } from "rxjs";
5
6 @Component({
7 selector: "my-app",
8 template: `
9 <h1>Retry And ReTryWhen Example</h1>
10 `,
11 styleUrls: ["./app.component.css"]
12 })
13 export class AppComponent {
14 ngOnInit() {
15 interval(1000)
16 .pipe(
17 map(val => {
18 if (val > 2) throw new Error("Invalid Value");
19 return val;
20 }),
21 retryWhen(
22 error => error.pipe(
23 tap(() => console.log("Retrying... "))))
24 )
25 .subscribe(
26 val => console.log(val),
27 err => console.log(err),
28 () => console.log("Complete")
29 );
30 }
31 }
32
33 **Console **
34
35
36 0
37 1
38 2
39 Retrying..
40 0
41 1
42 2
43 Retrying..
44
Source Code
Returning the error observable as it is also retries the source indefinitely
1
2 interval(1000)
3 .pipe(
4 map(val => {
5 if (val > 2) throw new Error("Invalid Value");
6 return val;
7 }),
8 retryWhen(error => error)
9 )
10 .subscribe(
11 val => console.log(val),
12 err => console.log(err),
13 () => console.log("Complete")
14 );
15
Source Code
Adding a Delay
The following code adds delay of 2000 ms.
1
2 interval(1000)
3 .pipe(
4 map(val => {
5 if (val > 2) throw new Error("Invalid Value");
6 return val;
7 }),
8 retryWhen(
9 error =>
10 error.pipe(
11 tap(() => console.log("error occurred ")),
12 delay(2000),
13 tap(() => console.log("Retrying ..."))
14 )
15 )
16 )
17 .subscribe(
18 val => console.log(val),
19 err => console.log(err),
20 () => console.log("Complete")
21 );
22
Source Code
Notifier observable
As long as the notifier observable emits a value, the retryWhen will re subscribes to the source again.
In the following example, we switch observable to a new observable using SwitchMap operator. The new observable
(of Operator) emits the value 1 after a delay of 1000 ms and the source is resubscribed again.
1
2 interval(1000)
3 .pipe(
4 map(val => {
5 if (val > 2) throw new Error("Invalid Value");
6 return val;
7 }),
8 retryWhen(error =>
9 error.pipe(
10 switchMap(() =>
11 of(1).pipe(
12 delay(1000),
13 tap(() => console.log("of emitted"))
14 )
15 ),
16 tap(() => console.log("Retrying ..."))
17 )
18 )
19 )
20 .subscribe(
21 val => console.log(val),
22 err => console.log(err),
23 () => console.log("Complete")
24 );
25
Source Code
The following uses of() instead of(1). of() does not emit any values but sends a complete notification on subscription.
In this case, RetryWhen does not retry the source but completes. The subscribers will not receive any notification.
1
2 interval(1000)
3 .pipe(
4 map(val => {
5 if (val > 2) throw new Error("Error: Value greater than 2");
6 return val;
7 }),
8 retryWhen(error =>
9 error.pipe(
10 switchMap(() =>
11 of().pipe(
12 delay(1000),
13 tap(() => console.log("of emitted"))
14 )
15 ),
16 tap(() => console.log("Retrying ..."))
17 )
18 )
19 )
20 .subscribe(
21 val => console.log(val),
22 err => console.error(err),
23 () => console.log("Complete")
24 );
25
Source Code
Here is another interesting example where we switch to interval(3000) observable.
When the error occurs the first time in the source, RetryWhen triggers the interval(3000). When it emits a value
source is re-subscribed.
But, the interval(3000) is going to emit another value after 3000ms. In this case, the RetryWhen will re subscribes to
the source again, even if the source has errored out or already completed.
1
2 interval(1000)
3 .pipe(
4 map(val => {
5 if (val > 2) throw Error;
6 return val;
7 }),
8 retryWhen(error =>
9 error.pipe(
10 tap(() => console.log("error tapped")),
11 switchMap(() =>
12 interval(3000).pipe(tap(() => console.log("interval")))
13 ),
14 tap(() => console.log("Retrying ..."))
15 )
16 )
17 )
18 .subscribe(
19 val => console.log(val),
20 err => console.log(err),
21 () => console.log("Complete")
22 );
23
24 *** Console ***
25 0
26 1
27 2
28 error tapped
29 interval
30 Retrying ...
31 0
32 1
33 interval
34 Retrying ...
35 0
36 1
37 interval
38 Retrying ...
39
40
Source Code
Limiting Retry Attempts
In the example below, we use the scan operator to count the number of tries and throw an error if the number of
attempts exceeds 2.
1
2 interval(1000)
3 .pipe(
4 map(val => {
5 if (val > 2) throw new Error("Invalid Value");
6 return val;
7 }),
8 retryWhen(error =>
9 error.pipe(
10 scan((acc, error) => {
11 if (acc > 2) throw error;
12 console.log("attempt " + acc);
13 return acc + 1;
14 }, 1),
15 delay(3000),
16 tap(() => console.log("Retrying ..."))
17 )
18 )
19 )
20 .subscribe(
21 val => console.log(val),
22 err => console.error(err),
23 () => console.log("Complete")
24 );
25
26
27 *** Console ***
28 0
29 1
30 2
31 attempt 1
32 Retrying ...
33 0
34 1
35 2
36 attempt 2
37 Retrying ...
38 0
39 1
40 2
41 Invalid Value
42
43
Source Code
Use the dealyWhen to increase the time duration between each retries.
1
2 interval(1000)
3 .pipe(
4 map(val => {
5 if (val > 2) throw new Error("Invalid Value");
6 return val;
7 }),
8 retryWhen(error =>
9 error.pipe(
10 scan((acc, error) => {
11 if (acc > 2) throw error;
12 console.log("attempt " + acc);
13 return acc + 1;
14 }, 1),
15 delayWhen(val => timer(val * 2000)),
16 tap(() => console.log("Retrying ..."))
17 )
18 )
19 )
20 .subscribe(
21 val => console.log(val),
22 err => console.error(err),
23 () => console.log("Complete")
24 );
25
Source Code
You can also use the take or takeWhile operator to stop the retries and emit the complete notification.
1
2 interval(1000)
3 .pipe(
4 map(val => {
5 if (val > 2) throw new Error("Invalid Value");
6 return val;
7 }),
8 retryWhen(error =>
9 error.pipe(
10 scan((acc, error) => {
11 console.log("attempt " + acc);
12 return acc + 1;
13 }, 1),
14 take(2),
15 delayWhen(val => timer(val * 2000)),
16 tap(() => console.log("Retrying ..."))
17 )
18 )
19 )
20 .subscribe(
21 val => console.log(val),
22 err => console.error(err),
23 () => console.log("Complete")
24 );
25 }
26
Unsubscribing from an Observable in Angular
1 Comment / 6 minutes of reading / May 16, 2021
ReTry & ReTryWhen
Subjects in Angular

In this tutorial let us learn how to Unsubscribe from an observable in angular. An observable which is not
Unsubscribed will lead to memory leak & Performance degradation.
Table of Contents
Why Unsubscribe
How to Unsubscribe
When to Unsubscribe
Various ways to Unsubscribe
Use Async Pipe
Using Take or First Operator
Use Unsubscribe
Using Array to store subscription
Using TakeUntil
Using TakeUntil in a base component
Reference
Why Unsubscribe
In the example below, we have ChildComponent, which subscribes to an observable in its ngOnInit hook. The
observable emits a new value for every 2000 ms.
In the AppComponent, we use the ngIf to show and remove the ChildComponent.
app.component.html
1
2 <h1>Angular Unsubscribe from Observable Example</h1>
3
4 Show Child :
5 <input
6 type="checkbox"
7 id="showChild"
8 name="showChild"
9 import { Component, VERSION } from "@angular/core";
10
11 @Component({
12 selector: "my-app",
13 template: `
14 <h1>Angular Unsubscribe from Observable Example</h1>
15
16 Show Child :
17 <input
18 type="checkbox"
19 id="showChild"
20 name="showChild"
21 [(ngModel)]="showChild"
22 />
23
24 <app-child-component *ngIf="showChild"></app-child-component>
25 `,
26 styleUrls: ["./app.component.css"]
27 })
28 export class AppComponent {
29 name = "Angular " + VERSION.major;
30
31 showChild = false;
32 }
33
34
Child.Component.ts
1
2 import { Component, OnInit } from "@angular/core";
3 import { timer, interval } from "rxjs";
4
5 @Component({
6 selector: "app-child-component",
7 templateUrl: "./child.component.html",
8 styleUrls: ["./child.component.css"]
9 })
10 export class ChildComponent implements OnInit {
11 src = interval(2000);
12 id = Date.now();
13
14 constructor() {}
15
16 ngOnInit() {
17 console.log("Component Created " + this.id);
18
19 this.src.subscribe(value => {
20 console.log("Received " + this.id);
21 });
22 }
23
24 ngOnDestroy() {
25 console.log("Component Destroyed " + this.id);
26 }
27 }
28
29
Source Code
The subscription starts to emit values when the child component is rendered by Angular. But when we destroy the
component, the observable still keeps emitting new values. We can see this in console window.
If we render the child component again, it starts a new subscription. Now we have two subscriptions running. As and
when we create a new instance of the child component, it will create a new subscription, and those subscriptions
never cleaned up.

How to Unsubscribe
Unsubscribing from an observable as easy as calling 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
1
2 obs: Subscription;
3
Assign the subscription to the obs variable
1
2 this.obs = this.src.subscribe(value => {
3 console.log("Received " + this.id);
4 });
5
6
Call the unsubscribe() method in the ngOnDestroy method.
1
2 ngOnDestroy() {
3 this.obs.unsubscribe();
4 }
5
6
When we destroy the component, the observable is unsubscribed and cleaned up.
The final code is shown below
Child.Component.ts
1
2 import { Component, OnInit } from "@angular/core";
3 import { timer, interval, Subscription } from "rxjs";
4
5 @Component({
6 selector: "app-child-component",
7 templateUrl: "./child.component.html",
8 styleUrls: ["./child.component.css"]
9 })
10 export class ChildComponent implements OnInit {
11 src = interval(2000);
12 id = Date.now();
13 obs: Subscription;
14
15 constructor() {}
16
17 ngOnInit() {
18 console.log("Component Created " + this.id);
19
20 this.obs = this.src.subscribe(value => {
21 console.log("Received " + this.id);
22 });
23 }
24
25 ngOnDestroy() {
26 console.log("Component Destroyed " + this.id);
27 this.obs.unsubscribe();
28 }
29 }
30
31
Source Code
When to Unsubscribe
There is no need to unsubscribe from every subscription. For Example, the observables, which are finite in nature.
Although it does not harm if you do so.
In Angular you do not have to Unsubscribe in the following scenarios
The HttpClient Observables like HTTP get & post, etc. They Complete after returning only one value.
The Angular Router also emits several observables like paramMap, queryParamMap, fragment, data, URL, Events,
etc. The Router Modules take care of unsubscribing.
All finite observables.
You need to Unsubscribe in the following scenarios
Any Observable that you create in your Angular component or Angular services.
ValueChanges & StatusChanges observables from Angular Forms
The listens to the DOM events from the Renderer2 service
All infinite observables.
When in doubt, always Unsubscribe
Various ways to Unsubscribe
Use Async Pipe
Use Async pipe to subscribe to an observable, it automatically cleans up, when we destroy the component.
Using Take or First Operator
Convert all infinite observables to finite observable using the Take or First Operators.
The Take Operator emits the first n number of values and then stops the source observable.
1
2 export class AppComponent {
3
4 obs = of(1, 2, 3, 4, 5).pipe(take(2));
5
6 ngOnInit() {
7 this.obs.subscribe(val => console.log(val));
8 }
9 }
10
11 ****Console ******
12 1
13 2
14
The first operator emits the first value and then stops the observable. But It sends an error notification if does not
receive any value.
1
2 export class AppComponent {
3
4 obs = of(1, 2, 3, 4, 5).pipe(first());
5
6 ngOnInit() {
7 this.obs.subscribe(val => console.log(val));
8 }
9 }
10
11 ****Console ******
12 1
13
14
Use Unsubscribe
Using Unsubscribe is the simplest & easiest way.
Store each subscription in a local variable and call unsubscribe on them in the ngOnDestroy hook
1
2 import { Component, OnInit } from "@angular/core";
3 import { timer, interval, Subscription } from "rxjs";
4
5 @Component({
6 selector: "app-child-component",
7 templateUrl: "./child.component.html",
8 styleUrls: ["./child.component.css"]
9 })
10 export class ChildComponent implements OnInit {
11 src1 = interval(1000);
12 src2 = interval(1500);
13 src3 = interval(2000);
14
15 id = Date.now();
16 obs1: Subscription;
17 obs2: Subscription;
18 obs3: Subscription;
19
20 constructor() {}
21
22 ngOnInit() {
23 console.log("Component Created " + this.id);
24
25 this.obs1 = this.src1.subscribe(value => {
26 console.log("Src1 " + this.id);
27 });
28
29 this.obs2 = this.src2.subscribe(value => {
30 console.log("Src2 " + this.id);
31 });
32
33 this.obs3 = this.src3.subscribe(value => {
34 console.log("Src3 " + this.id);
35 });
36 }
37
38 ngOnDestroy() {
39
40 if (this.obs1) this.obs1.unsubscribe();
41 if (this.obs2) this.obs2.unsubscribe();
42 if (this.obs3) this.obs3.unsubscribe();
43
44 console.log("Component Destroyed " + this.id);
45 }
46 }
47
48
Source Code
Using Array to store subscription
Instead of local variable for each subscription, you can create an array and add each subscription into it
1
2 let subs: Subscription[] = [];
3
Push each subscriptions to array
1
2 this.subs.push(
3 this.src1.subscribe(value => {
4 console.log("Src1 " + this.id);
5 })
6 );
7
In the ngOnDestroy hook, call unsubscribe on each subscriptions
1
2 ngOnDestroy() {
3 this.subs.forEach(sub => sub.unsubscribe());
4
5 console.log("Component Destroyed " + this.id);
6 }
7
Source Code
Using TakeUntil
We can make use of TakeUntil Operator.
The takeUntil operator emits values from the source observable until the notifier Observable emits a value. It then
completes the source observable.
To use takeUntil first, we create a notifier observable stop$
1
2 stop$ = new Subject<void>();
3
4
This notifier observable emits a value when the component is destroyed. We do that in ngOnDestroy hook.
1
2 ngOnDestroy() {
3 this.stop$.next();
4 this.stop$.complete();
5 }
6
7
We add the takeUntil(this.stop$) to all the observable we subscribe. When the component is destroyed all of them
automatically unsubscribed. Remember to add it to the last in the pipe Operator.
1
2 this.src.pipe(takeUntil(this.stop$)).subscribe(value => {
3 console.log("Obs1 " + this.id);
4 });
5
6
Complete code.
1
2 import { Component, OnInit } from "@angular/core";
3 import { timer, interval, Subscription, Subject } from "rxjs";
4 import { takeUntil } from "rxjs/operators";
5
6 @Component({
7 selector: "app-child-component",
8 templateUrl: "./child.component.html",
9 styleUrls: ["./child.component.css"]
10 })
11 export class ChildComponent implements OnInit {
12 stop$ = new Subject<void>();
13 src = interval(2000);
14
15 id = Date.now();
16
17 constructor() {}
18
19 ngOnInit() {
20 console.log("Component Created " + this.id);
21
22 this.src.pipe(takeUntil(this.stop$)).subscribe(value => {
23 console.log("Obs1 " + this.id);
24 });
25
26 this.src.pipe(takeUntil(this.stop$)).subscribe(value => {
27 console.log("Obs2 " + this.id);
28 });
29 }
30
31 ngOnDestroy() {
32 this.stop$.next();
33 this.stop$.complete();
34 console.log("Component Destroyed " + this.id);
35 }
36 }
37
Source Code
Using TakeUntil in a base component
Instead of creating the notifier observable in every component, you can create on in a BaseComponent and reuse it
everywhere.
base.component.ts
1
2 import { Component, OnDestroy } from "@angular/core";
3 import { Subject } from "rxjs";
4
5 @Component({
6 template: ``
7 })
8 export class BaseComponent implements OnDestroy {
9 stop$ = new Subject<void>();
10
11 ngOnDestroy() {
12 this.stop$.next();
13 this.stop$.complete();
14 console.log("BaseComponent Destroyed ");
15 }
16 }
17
18
Extend every component using BaseComponent.
child.component.ts
1
2 import { Component, OnInit } from "@angular/core";
3 import { timer, interval, Subscription, Subject } from "rxjs";
4 import { takeUntil } from "rxjs/operators";
5 import { BaseComponent } from "../base.component";
6
7 @Component({
8 selector: "app-child-component",
9 templateUrl: "./child.component.html",
10 styleUrls: ["./child.component.css"]
11 })
12 export class ChildComponent extends BaseComponent implements OnInit {
13 src = interval(2000);
14
15 id = Date.now();
16
17 constructor() {
18 super();
19 }
20
21 ngOnInit() {
22 console.log("Component Created " + this.id);
23
24 this.src.pipe(takeUntil(this.stop$)).subscribe(value => {
25 console.log("Obs1 " + this.id);
26 });
27
28 this.src.pipe(takeUntil(this.stop$)).subscribe(value => {
29 console.log("Obs2 " + this.id);
30 });
31 }
32
33 ngOnDestroy() {
34 super.ngOnDestroy();
35 console.log("Component Destroyed " + this.id);
36 }
37 }
38
39
Source Code
Note that if you wish you use the constructor or ngOnDestroy in the child component, then remember to use
the super & super.ngOnDestroy() to call the base constructor & ngOnDestroy of the base component.
Parent to Child: Sharing Data via Input
This is probably the most common and straightforward method of sharing data. It works by using
the @Input() decorator to allow data to be passed via the template.
parent.component.ts
import { Component } from '@angular/core';

@Component({
selector: 'app-parent',
template: `
<app-child [childMessage]="parentMessage"></app-child>
`,
styleUrls: ['./parent.component.css']
})
export class ParentComponent{
parentMessage = "message from parent"
constructor() { }
}
child.component.ts
import { Component, Input } from '@angular/core';

@Component({
selector: 'app-child',
template: `
Say {{ message }}
`,
styleUrls: ['./child.component.css']
})
export class ChildComponent {

@Input() childMessage: string;

constructor() { }

}
Child to Parent: Sharing Data via ViewChild
ViewChild allows a one component to be injected into another, giving the parent access to its attributes and
functions. One caveat, however, is that child won’t be available until after the view has been initialized. This means
we need to implement the AfterViewInit lifecycle hook to receive the data from the child.
parent.component.ts
import { Component, ViewChild, AfterViewInit } from '@angular/core';
import { ChildComponent } from "../child/child.component";

@Component({
selector: 'app-parent',
template: `
Message: {{ message }}
<app-child></app-child>
`,
styleUrls: ['./parent.component.css']
})
export class ParentComponent implements AfterViewInit {

@ViewChild(ChildComponent) child;
constructor() { }

message:string;

ngAfterViewInit() {
this.message = this.child.message
}
}
child.component.ts
import { Component} from '@angular/core';

@Component({
selector: 'app-child',
template: `
`,
styleUrls: ['./child.component.css']
})
export class ChildComponent {

message = 'Hola Mundo!';

constructor() { }

}
Child to Parent: Sharing Data via Output() and EventEmitter
Another way to share data is to emit data from the child, which can be listened to by the parent. This approach is
ideal when you want to share data changes that occur on things like button clicks, form entires, and other user
events.
In the parent, we create a function to receive the message and set it equal to the message variable.
In the child, we declare a messageEvent variable with the Output decorator and set it equal to a new event emitter.
Then we create a function named sendMessage that calls emit on this event with the message we want to send.
Lastly, we create a button to trigger this function.
The parent can now subscribe to this messageEvent that’s outputted by the child component, then run the receive
message function whenever this event occurs.
parent.component.ts
import { Component } from '@angular/core';

@Component({
selector: 'app-parent',
template: `
Message: {{message}}
<app-child (messageEvent)="receiveMessage($event)"></app-child>
`,
styleUrls: ['./parent.component.css']
})
export class ParentComponent {

constructor() { }

message:string;

receiveMessage($event) {
this.message = $event
}
}
child.component.ts
import { Component, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-child',
template: `
<button (click)="sendMessage()">Send Message</button>
`,
styleUrls: ['./child.component.css']
})
export class ChildComponent {

message: string = "Hola Mundo!"

@Output() messageEvent = new EventEmitter<string>();

constructor() { }

sendMessage() {
this.messageEvent.emit(this.message)
}
}
Unrelated Components: Sharing Data with a Service
When passing data between components that lack a direct connection, such as siblings, grandchildren, etc, you
should have a shared service. When you have data that should aways been in sync, I find the RxJS
BehaviorSubject very useful in this situation.
You can also use a regular RxJS Subject for sharing data via the service, but here’s why I prefer a BehaviorSubject.
It will always return the current value on subscription - there is no need to call onnext
It has a getValue() function to extract the last value as raw data.
It ensures that the component always receives the most recent data.
In the service, we create a private BehaviorSubject that will hold the current value of the message. We define a
currentMessage variable handle this data stream as an observable that will be used by the components. Lastly, we
create function that calls next on the BehaviorSubject to change its value.
The parent, child, and sibling components all receive the same treatment. We inject the DataService in the
constructor, then subscribe to the currentMessage observable and set its value equal to the message variable.
Now if we create a function in any one of these components that changes the value of the message. when this
function is executed the new data it’s automatically broadcast to all other components.
data.service.ts
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Injectable()
export class DataService {

private messageSource = new BehaviorSubject('default message');


currentMessage = this.messageSource.asObservable();

constructor() { }

changeMessage(message: string) {
this.messageSource.next(message)
}

}
parent.component.ts
import { Component, OnInit } from '@angular/core';
import { DataService } from "../data.service";
import { Subscription } from 'rxjs';
@Component({
selector: 'app-parent',
template: `
{{message}}
`,
styleUrls: ['./sibling.component.css']
})
export class ParentComponent implements OnInit, OnDestroy {

message:string;
subscription: Subscription;

constructor(private data: DataService) { }

ngOnInit() {
this.subscription = this.data.currentMessage.subscribe(message => this.message = message)
}

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

}
sibling.component.ts
import { Component, OnInit } from '@angular/core';
import { DataService } from "../data.service";
import { Subscription } from 'rxjs';

@Component({
selector: 'app-sibling',
template: `
{{message}}
<button (click)="newMessage()">New Message</button>
`,
styleUrls: ['./sibling.component.css']
})
export class SiblingComponent implements OnInit, OnDestroy {

message:string;
subscription: Subscription;

constructor(private data: DataService) { }

ngOnInit() {
this.subscription = this.data.currentMessage.subscribe(message => this.message = message)
}

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

newMessage() {
this.data.changeMessage("Hello from Sibling")
}

}
Introduction
Directives are a very important feature provided by Angular. Even Angular Components are actually higher-order
directives with their own template.
In this guide, we'll look into the various types of directives and then learn how to build one for our application's
custom requirements.
Types of Directives
Angular has two main types of directives:
Attribute
Structural
Attribute Directives
Attribute directives get applied to the element's attributes. Thus, they are useful to manipulate our DOM by
updating certain attributes but do not create or destroy element's as such. Thus, they can also be referred to as
DOM-friendly directives. They only change the DOM element they are attached to. They mostly use data binding or
event binding.
They can be useful in the following scenarios:
Applying styles or classes to certain elements conditionally
Example below:
1<div [style.color]="'green'">Very excited to learn about building Custom Directives !!</div>
html
Showing or hiding elements conditionally
Example below:
1<div [hidden]="showHideEl">Very excited to learn about building Custom Directives !!</div>
html
Changing the behavior of any component dynamically, depending on any property
Structural Directives
Structural directives, on the other hand, can create, delete, or re-create DOM elements based on certain inputs.
Thus, they are generally not DOM-friendly.
Let's talk about what the "hidden" attribute directive does. It retains the element in the DOM, but only hides it from
the user, while structural directives such as *ngIf remove the element from the DOM.
The other commonly used structural directives are ngFor and ngSwitch which can be used for routing programming
tasks.
Custom Directive
There are many use cases in our app, where we have a custom requirement and have to create a custom directive as
per our requirement. This is where we'll need to create a custom directive.
Angular has some basic APIs which can help us create custom directives. Let us first have a look at creating a custom
attribute directive.
Custom Attribute Directives
Say we have a requirement where we want any element to be styled in a particular way (e.g. with a background
highlight color and some text/foreground color). We can have such a text in multiple places, so we can create a
custom directive for the same and reuse it across our application. So essentially, we want to be able to use our
directive as below:
1<div class="para float-left" myHighlight>Some text to be highlighted !</div>
html
To create the directive, we can run the following command using the Angular CLI:
1ng generate directive myHighlight
The above command would automatically update the entry in our app.module.ts. However, if we create the directive
manually, we'll need to update this in our AppModule as below:
1import { NgModule } from '@angular/core';
2import { BrowserModule } from '@angular/platform-browser';
3import { AppComponent } from './app.component';
4
5import { MyHighlightDirective } from './myhighlight.directive';
6
7@NgModule({
8 imports: [ BrowserModule ],
9 declarations: [
10 AppComponent,
11 MyHighlightDirective
12 ],
13 bootstrap: [ AppComponent ]
14})
15export class AppModule { }
javascript
The above would inform Angular about our new directive and this is how it knows which class to invoke whenever it
encounters the selector in the template.
We'll now start with the decorator. So, any directive class has to be annotated by using a @Directive decorator.
Let us create a class called "MyHighlightDirective" and then use the @Directive decorator to associate our class with
the attribute "myHighlight", as shown below:
1import { Directive } from '@angular/core';
2//...
3//...
4//...
5@Directive({
6 selector:"[myHighlight]"
7})
8export class MyHighlightDirective { }
javascript
As you can see, we marked the class using the @Directive decorator and have to import the same from
@angular/core.
Also, the code shown above is quite similar to how we write a component. One of the differences we can see is that
our selector is wrapped inside []. This is because our selector attribute internally uses the same CSS matching rules to
match any directive or component and map it to any HTML element.
Thus, if we have to select any particular element via CSS, we just write the name of the element like say div
{background-color: 'green'}. And this is why, in the selector for the component in the @Component directive, we just
specify the name of the component.
If we update the selector in our directive as below:
1import { Directive } from '@angular/core';
2//...
3//...
4//...
5@Directive({
6 selector:".myHighlight"
7})
8export class MyHighlightDirective { }
javascript
With the above definition, our directive would be associated with any element which has a class "myHighlight"
defined like:
1<div class="para float-left myHighlight">Some text to be highlighted !</div>
html
For now, let us associate our directive to an element with the attribute "myHighlight".
Once we have our decorator added, the next step would be to add a constructor to our directive, as shown below:
1import { Directive } from '@angular/core';
2import { ElementRef } from '@angular/core';
3//...
4//...
5//...
6@Directive({
7 selector:"[myHighlight]"
8})
9export class MyHighlightDirective {
10 constructor(private elRef: ElementRef) {}
11}
javascript
With the above code, we are telling Angular to inject an instance of ElementRef into its constructor, whenever the
directive is created. This is actually via dependency injection.
ElementRef is used to get direct access to the DOM element on which our directive attribute is attached to.
Let's say we now want to change the background color of this element to green and the foreground color to blue. To
do that, we'll write the following code:
1el.nativeElement.style.backgroundColor = "green";
2el.nativeElement.style.color = "blue";
javascript
ElementRef is actually a wrapper for our actual DOM element and we access the DOM element using the property
nativeElement on it.
We'll write the above code inside our ngOnInit method. So this is how our directive class would now look like;
1import { Directive } from '@angular/core';
2import { ElementRef } from '@angular/core';
3//...
4//...
5//...
6@Directive({
7 selector:"[myHighlight]"
8})
9export class MyHighlightDirective {
10 constructor(private elRef: ElementRef) {}
11 ngOnInit() {
12 this.elRef.nativeElement.style.backgroundColor = "green";
13 this.elRef.nativeElement.style.color = "blue";
14 }
15}
javascript
The only issue with the above style of using directives is that this would assume that our app would always run in a
browser. However, that might not be the case always. We can have our app running in a different environment like
on a native mobile device. Thus, Angular has provided with an API which is platform independent and we can set
properties on our elements using Renderer.
This is how our class would get updated to if we use the Renderer helper:
1import { Directive } from '@angular/core';
2import { Renderer } from '@angular/core';
3//...
4//...
5//...
6@Directive({
7 selector:"[myHighlight]"
8})
9export class MyHighlightDirective {
10 constructor(private elRef: ElementRef, private renderer: Renderer) {}
11 ngOnInit() {
12 this.renderer.setStyle(this.elRef.nativeElement, 'background-color', 'green');
13 this.renderer.setStyle(this.elRef.nativeElement, 'color', 'blue');
14 }
15}
javascript
The "setStyle" method has the following signature:
1setStyle(element: any, style: string, value: any, flags?: RendererStyleFlags2): void
javascript
Thus, we are now updating our DOM element's style (background and foreground color) via the "Renderer" and not
directly accessing our element, which is a good practice.
We are now applying a hardcoded background and foreground colors to the DOM element. Let's say that we want
that to be configurable, meaning our DOM element can say that it needs the background color and foreground color
to be something specific. Thus, we want to be able to say:
1<div class="para float-left" myHighlight [backgroundColor]="'black'" [foregroundColor]="'white'">Some text to be
highlighted !</div>
html
The above can be achieved with the help of @Input decorator. We'll also use the @HostBinding decorator to update
the styles on our element. Let us update our class showing the use of @Input and @HostBinding:
1import { Directive } from '@angular/core';
2import { Input } from '@angular/core';
3import { HostBinding } from '@angular/core';
4//...
5//...
6//...
7@Directive({
8 selector:"[myHighlight]"
9})
10export class MyHighlightDirective {
11 @Input() backgroundColor:string = 'green';
12 @Input() foregroundColor:string = 'blue';
13 @HostBinding('style.backgroundColor') bgColor:string;
14 @HostBinding('style.color') color:string;
15 constructor() {}
16 ngOnInit() {
17 this.bgColor = this.backgroundColor;
18 this.color = this.foregroundColor;
19 }
20}
javascript
If you see the above code, we now have default values for the background and foreground colors (i.e. green and
blue). However, if the values are passed to the directive via data binding, we instead use those values to set the
styles on our element.
We can also attach event listeners to our directive. Say, we want our text to have a different background and
foreground colors when the user hovers over it. Thus, we want to be able to pass this to our directive:
1<div class="para float-left" myHighlight
2 [backgroundColor]="'black'"
3 [foregroundColor]="'white'"
4 [hoverBackgroundColor]="'yellow'"
5 [hoverForegroundColor]="'red'">Some text to be highlighted !</div>
html
To be able to do this, we'll need to use the @HostListener decorator as shown below:
1import { Directive } from '@angular/core';
2import { Input } from '@angular/core';
3import { HostBinding } from '@angular/core';
4import { HostListener } from '@angular/core';
5//...
6//...
7//...
8@Directive({
9 selector:"[myHighlight]"
10})
11export class MyHighlightDirective {
12 @Input() backgroundColor:string = 'green';
13 @Input() foregroundColor:string = 'blue';
14 @Input() hoverBackgroundColor:string = 'gray';
15 @Input() hoverForegroundColor:string = 'orange';
16 @HostBinding('style.backgroundColor') bgColor:string;
17 @HostBinding('style.color') color:string;
18 constructor() {}
19 ngOnInit() {
20 this.bgColor = this.backgroundColor;
21 this.color = this.foregroundColor;
22 }
23 @HostListener('mouseenter') onMouseEnter(eventData: Event) {
24 this.bgColor = this.hoverBackgroundColor;
25 this.color = this.hoverForegroundColor;
26 }
27}
javascript
Thus, host listeners are just event listeners that get attached to the DOM element which is hosting our directive.
Custom Structural Directive
Now that we have an understanding of the custom attribute directive, let us have a quick look at how we can create
a custom Structural Directive. We can try recreating the in-built ngIf directive. Let us call that as "myCustomIf". This
is how the class for that would look like:
1import { Directive} from '@angular/core';
2import { Input, TemplateRef, ViewContainerRef } from '@angular/core';
3
4@Directive({
5 selector: '[myCustomIf]'
6})
7export class myCustomIfDirective {
8 constructor(
9 private template: TemplateRef<any>,
10 private container: ViewContainerRef
11 ) { }
12
13 @Input() set myIf(shouldAddToDOM: boolean) {
14 if (shouldAddToDOM) {
15 // If the value is true, add template to the DOM
16 this.container.createEmbeddedView(this.template);
17 } else {
18 // Otherwise delete template from the DOM
19 this.container.clear();
20 }
21 }
22
23}
javascript
We can now use this directive anywhere in our app. To do that, we'll just write;
1<!-- /app/my.component.html -->
2<div *myCustomIf="false">
3 Inside if
4</div>
html
Conclusion
Thus, we can see that directives can be really useful to implement any sort of custom logic on our DOM element.
While a lot of common functionalities can be achieved with the help of inbuilt directives, it is not uncommon to have
custom requirements in any app and in such cases, we can always write our own custom directive to get the desired
result. Also, we can write both the types of directive i.e. Attribute directive and Structural directive.

What Are @HostBinding() and @HostListener() in Angular?


In this article, we go over how you can incorporate these two decorators into the TypeScript code you use to build
your Angular web app.

by
Dhananjay Kumar

·
Jan. 01, 18 · Tutorial
Like (14)

Comment (1)

Save

Tweet
230.86K Views
Join the DZone community and get the full member experience.
JOIN FOR FREE
To understand @HostListener and @HostBinding, you should have basic knowledge about directives in Angular.
There are three types of directives in Angular:
Component
Attribute Directive
Structural Directive
The basic difference between a component and a directive is that a component has a template, whereas an attribute
or structural directive does not have a template. To understand these two concepts, let us start by creating a simple
custom attribute directive. The directive below changes the background color of the host element:
1
import { Directive, ElementRef, Renderer } from '@angular/core';
2

3
@Directive({
4
selector: '[appChbgcolor]'
5
})
6
export class ChangeBgColorDirective {
7

8
constructor(private el: ElementRef, private renderer: Renderer) {
9
this.ChangeBgColor('red');
10
}
11

12
ChangeBgColor(color: string) {
13

14
this.renderer.setElementStyle(this.el.nativeElement, 'color', color);
15
}
16
}
To create a custom attribute directive, you need to create a class and decorate it with @Directive. In the constructor
of the directive class, inject the objects ElementRef and Renderer. Instances of these two classes are needed to get
the reference of the host element and of the renderer.
You can use the above attribute directive on a component template as shown in the code block below:
1
<div appChbgcolor>
2
<h3>{{title}}</h3>
3
</div>
Here, the component class holding the host element is created as below:
1
import { Component } from '@angular/core';
2

3
@Component({
4
selector: 'app-root',
5
templateUrl: './app.component.html',
6
styleUrls: ['./app.component.css']
7
})
8
export class AppComponent {
9
title = 'Hey ng Developer ! ';
10
}
Right now, the appChbgcolor directive will change the color of the host element.
@HostListener() Decorator
In Angular, the @HostListener() function decorator allows you to handle events of the host element in the directive
class.
Let's take the following requirement: when you hover you mouse over the host element, only the color of the host
element should change. In addition, when the mouse is gone, the color of the host element should change to its
default color. To do this, you need to handle events raised on the host element in the directive class. In Angular, you
do this using @HostListener() .
To understand @HostListener() in a better way, consider another simple scenario: on the click of the host element,
you want to show an alert window. To do this in the directive class, add @HostListener() and pass the event 'click' to
it. Also, associate a function to raise an alert as shown in the listing below:
1
@HostListener('click') onClick() {
2
window.alert('Host Element Clicked');
3
}
In Angular, the @HostListener() function decorator makes it super easy to handle events raised in the host element
inside the directive class. Let's go back to our requirement that says you must change the color to red only when the
mouse is hovering, and when it's gone, the color of the host element should change to black. To do this, you need to
handle the mouseenter and mouseexit events of the host element in the directive class. To achieve this, modify
the appChbgcolor directive class as shown below:
1
import { Directive, ElementRef, Renderer, HostListener } from '@angular/core';
2

3
@Directive({
4
selector: '[appChbgcolor]'
5
})
6
export class ChangeBgColorDirective {
7

8
constructor(private el: ElementRef, private renderer: Renderer) {
9
// this.ChangeBgColor('red');
10
}
11

12
@HostListener('mouseover') onMouseOver() {
13
this.ChangeBgColor('red');
14
}
15

16
@HostListener('click') onClick() {
17
window.alert('Host Element Clicked');
18
}
19
@HostListener('mouseleave') onMouseLeave() {
20
this.ChangeBgColor('black');
21
}
22

23
ChangeBgColor(color: string) {
24

25
this.renderer.setElementStyle(this.el.nativeElement, 'color', color);
26
}
27
}
In the directive class, we are handling the mouseenter and mouseexit events. As you see, we are using
@HostListener() to handle these host element events and assigning a function to it.
So, let's use @HostListener() function decorator to handle events of the host element in the directive class.
@HostBinding() Decorator
In Angular, the @HostBinding() function decorator allows you to set the properties of the host element from the
directive class.
Let's say you want to change the style properties such as height, width, color, margin, border, etc., or any other
internal properties of the host element in the directive class. Here, you'd need to use the @HostBinding() decorator
function to access these properties on the host element and assign a value to it in directive class.
The @HostBinding() decorator takes one parameter, the name of the host element property which value we want to
assign in the directive.
In our example, our host element is an HTML div element. If you want to set border properties of the host element,
you can do that using @HostBinding() decorator as shown below:
1
@HostBinding('style.border') border: string;
2

3
@HostListener('mouseover') onMouseOver() {
4
this.border = '5px solid green';
5
}
Using this code, on a mouse hover, the host element border will be set to a green, solid 5-pixel width. Therefore,
using the @HostBinding decorator, you can set the properties of the host element in the directive class.
Angular @HostBinding() and @HostListener() Example
November 13, 2022
Angular custom directives can take inputs using @HostBinding and add event listeners to elements
using @HostListener.
This Angular post is compatible with Angular 4 upto latest versions, Angular 7, Angular 8, Angular 9, Angular 10,
Angular 11, Angular 12 and Angular 13
In this tutorial, we will create a custom directive example from scratch which will take user inputs from a directive
element and use them in event listeners.
Let’s create a new Directive in the Angular application to demonstrate an element Highlighter directive which will
include color input by a user and mouse events to highlight the background of a div.

Create Directive [appHighlight]


To create a new directive we will use the generate command of ng cli. Run the following command in the terminal
window to creates a directive in directives folder :
$ ng generate directive directives/highlighter
Above command will create a new directive HighlighterDirective in the file src\app\directives\highlighter.directive.ts
// highlighter.directive.ts
import { Directive } from '@angular/core';

@Directive({
selector: '[appHighlighter]'
})
export class HighlighterDirective {

constructor() { }

}
Copy
To use a directive we also need to import it in the app.module.ts file's declaration array but NG CLI command will
automatically add it as shown below:
// app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';


import { AppComponent } from './app.component';
import { HighlighterDirective } from './directives/highlighter.directive';

@NgModule({
declarations: [
AppComponent,
HighlighterDirective
],
imports: [
BrowserModule,
AppRoutingModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Add Directive Element
Now we will add a <p/> tag element with some random text in the component template HTML with two properties:
[appHighlighter] : This property will act as the Directive selector added to the element as well as take a color name
or Hexacode, which will be the background color changed on the mouseenter event.
[defaultColor] : This property takes the color which will be added by default to the element.
Finally, the element with our directive will look like this:
<p
[appHighlighter]="'red'"
[defaultColor]="'yellow'"

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore
magna
aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
Update Directive with @HostBinding and @HostListener
Let's add @HostBinding and @HostListener decorators and check what actually they do in a directive?
What is @HostBinding in Angular?
The host is actually the element on which we have added the directive attribute selector. By using the @HostBinding
we can control the properties on the host element, on which we have applied the directive selector.
We will use this decorator to set the background color on the directive by controlling the style attribute from the
directive class itself.
@HostBinding('style.backgroundColor') backgroundColor: string;
Copy
What is @HostListener in Angular?
The @HostListener decorator enable event binding to the host element which we will use inside our directive class
to bind mouseenter and mouseleave event listeners.
@HostListener('mouseenter') mouseover(eventData: Event) {
...
}

@HostListener('mouseleave') mouseleave(eventData: Event) {


...
}
Copy
Moving to our directive class, add @input decorators to get values to form properties we bind to the <p> element.
Also, add @HostBinding for getting control over style attribute to change backgroundColor.
...
export class HighlighterDirective {
@Input() defaultColor: string = 'transparent';
@Input('appHighlighter') highlightColor: string = 'blue';
@HostBinding('style.backgroundColor') backgroundColor: string;
...
On class initialization, set the background color of the host, which is the <p> element here with the default color
using the ngOnInit() component hook.
...
ngOnInit() {
this.backgroundColor = this.defaultColor;
}
...
To control mouse behavior on the element, add event listeners as shown below:
...
@HostListener('mouseenter') mouseover(eventData: Event) {
this.backgroundColor = this.highlightColor;
}

@HostListener('mouseleave') mouseleave(eventData: Event) {


this.backgroundColor = this.defaultColor;
}
...
Copy
That's it now our complete HighlighterDirective class will finally have the following code!
// highlighter.directive.ts
import { Directive, Input, HostBinding, HostListener } from '@angular/core';

@Directive({
selector: '[appHighlighter]'
})
export class HighlighterDirective {

@Input() defaultColor: string = 'transparent';


@Input('appHighlighter') highlightColor: string = 'blue';
@HostBinding('style.backgroundColor') backgroundColor: string;

constructor() { }

ngOnInit() {
this.backgroundColor = this.defaultColor;
}

@HostListener('mouseenter') mouseover(eventData: Event) {


this.backgroundColor = this.highlightColor;
}

@HostListener('mouseleave') mouseleave(eventData: Event) {


this.backgroundColor = this.defaultColor;
}

Conclusion: Here we discussed how to control the element behavior by adding a custom directive using
@HostBinding and @HostListener interface
=======================================================================================

You might also like