Angular allows us to trigger the actions at the specific point in the lifecycle of our components. Whenever data bound input property value changes occur or any view render or any component created or destroyed the lifecycle hooks will be called. So any operations performed on the DOM elements will be do using the lifecycle hooks.
If a component created then the lifecycle hooks will be called in the following sequence:
1. ngOnChanges:
This hook will be called every time when a data bound input element value changes. This method receives the current value or previous value of the data bound input property. First time it will be called before ngOnInit() hook.
2. ngOnInit():
This hook will be called whenever any component initialized. This will be called after the constructor() and ngOnChanges().
3. ngDoCheck():
This hook will be called on every change detections on input property or DOM elements. This will be called after ngOnInit() and ngOnChanges().
4. ngAfterContentInit():
This hook will be called whenever any component content is initialized.
5. ngAfterContentChecked():
This hook will be called after the content of the component has been checked.
6. ngAfterViewInit():
This hook will be called after the component view initialized.
7. ngAfterViewChecked():
This hook will be called after the view of the component has been checked.
8. ngOnDestroy():
This hook will be called when the component is destroyed. It is used to cleanup or unsubscribe the observables of the component.
In this article we are explaining how to use ngOnChanges(), ngOnInit(), ngAfterViewInit() hooks with a example.
Creating new angular project:
Create a new angular project by running the command
ng new lifecycleHooksDemo
This creates lifecycleHooksDemo angular repository
ngOnChange() hook example:
Here we are working on ngOnChanges() hook. On change the input property of the child component triggering the ngOnChanges() hook and assigning the previous value of the input property to the name property.
Create child component by running the command
ng generate component /components/childComponent
This will create child-component in .src/app/components folder
Load the child component in app.component
.src/app/app.component.html
<div>
<h1>
Lifecycle Hooks
</h1>
</div>
<div>
<app-child-component [title]=’parentTitle’></app-child-component>
<button (click)=’onClick()’>Change Value</button>
</div>
Here parentTitle property value is the assigning to the title and passing as input property.
.src/app/app.component.ts
import { Component } from ‘@angular/core’;
@Component({
selector: ‘app-root’,
templateUrl: ‘./app.component.html’,
styleUrls: [‘./app.component.css’]
})
export class AppComponent {
parentTitle: string;
counter = 1;
constructor() { }
onClick() {
this.parentTitle = `Hello Angular: ${this.counter}`;
this.counter++;
}
}
Here on click button incrementing the counter value and updating the parentTitle property.
.src/app/components/child-component/child-component.component.html
<p>{{name}}</p>
<div>
<input type="text" [(ngModel)]="title" placeholder="Enter title">
</div>
.src/app/component/child-component/child-component.component.ts
import { Component, OnChanges, Input, SimpleChanges } from ‘@angular/core’;
@Component({
selector: ‘app-child-component’,
templateUrl: ‘./child-component.component.html’,
styleUrls: [‘./child-component.component.css’]
})
export class ChildComponentComponent implements OnChanges {
@Input() title: string;
name: string;
constructor() { }
ngOnChanges(changes: SimpleChanges) {
console.log(‘in ngOnChanges’);
for (const propName in changes) {
let change = changes[propName];
if (change.isFirstChange()) {
console.log(`first change: ${propName}`);
} else {
this.name = change.previousValue;
console.log(`prev: ${change.previousValue}, cur: ${change.currentValue}`);
}
}
}
}
Here on change title input property triggers the ngOnChanges() method. In ngOnChanges() method get the previous value of the input title property and assigning the value to the name property.
ngOnInit() Example:
In this example we are updating the child component name property in parent component ngOnInit() method. Here we are creating the child component reference (#childComponent) and declaring using ViewChild decorator. Using childComponent reference we are updating the name property.
Once the component initialize the ngOnInit() hook will be called and update the child component name property.
.src/app/app.component.ts
import { Component, OnInit, ViewChild } from ‘@angular/core’;
import { ChildComponentComponent } from ‘./components/child-component/child-component.component’;
@Component({
selector: ‘app-root’,
templateUrl: ‘./app.component.html’,
styleUrls: [‘./app.component.css’]
})
export class AppComponent implements OnInit {
@ViewChild(‘childComponent’) childComponent: ChildComponentComponent;
parentTitle: string;
counter = 1;
constructor() { }
onClick() {
this.parentTitle = `Hello Angular: ${this.counter}`;
this.counter++;
}
ngOnInit() {
this.childComponent.name = ‘Hello World!’;
}
}
ngAfterViewInit() Example:
ngAfterViewInit() will be called after initializing the app component view and its child components views. Here we are creating the element reference(#pTag) for a paragraph tag and declaring in the app component using ViewChild decorator. Using the element refernce updating the paragraph text content in ngAfterViewInit() hook.
.src/app/app.component.html
<div>
<h1>
Lifecycle Hooks
</h1>
</div>
<div>
<app-child-component [title]=’parentTitle’ #childComponent></app-child-component>
<button (click)=’onClick()’>Change Value</button>
</div>
<p #pTag>Before view init</p>
.src/app/app.component.ts
import { Component, OnInit, ViewChild, AfterViewInit, ElementRef } from ‘@angular/core’;
import { ChildComponentComponent } from ‘./components/child-component/child-component.component’;
@Component({
selector: ‘app-root’,
templateUrl: ‘./app.component.html’,
styleUrls: [‘./app.component.css’]
})
export class AppComponent implements OnInit, AfterViewInit {
@ViewChild(‘childComponent’) childComponent: ChildComponentComponent;
@ViewChild(‘pTag’) pTag: ElementRef;
parentTitle: string;
counter = 1;
constructor() { }
onClick() {
this.parentTitle = `Hello Angular: ${this.counter}`;
this.counter++;
}
ngOnInit() {
console.log(‘ngOnInit’);
this.childComponent.name = ‘Hello World!’;
}
ngAfterViewInit() {
console.log(‘AfterViewInit’);
const element = <HTMLElement>this.pTag.nativeElement;
element.textContent = ‘Alter text after view init.’;
}
}
You can refer the example here: https://github.com/KtreeOpenSource/AngularExamples/tree/master/lifecycleHooksDemo