Component Life Cycle In Angular
In this article, we will learn how to use Angular lifecycle hooks. The life cycle hooks are the techniques that angular uses to generate, update, and destroy directives and components. We may fine-tune the behavior of our components during their creation, updating, and removal by using lifecycle hooks.
What are lifecycle hooks in Angular Components?
The root component is created and rendered when the angular application starts. It then generates and renders its children and their descendants. It forms a component tree.
Angular begins rendering the view after the components have been loaded. To do so, it must examine input properties, analyze data bindings and expressions, generate projected information, and so on. When a component is no longer required, Angular removes it from the DOM.
Angular uses lifecycle hooks to notify us when certain events occur.
Angular life cycle hooks are simply callback functions that Angular calls when a specific event occurs during the component's life cycle.
For example,
- When Angular first initializes the component, it calls ngOnInit.
- Angular calls ngOnChanges when the input property of a component changes.
- Angular calls ngOnDestroy when a component is destroyed.
Lifecycle hooks in angular
The following is a list of all the life cycle hooks that angular uses during the component life cycle. When a specific event occurs, Angular calls them up.
- ngOnChanges
- ngOnInit
- ngDoCheck
- ngAfterContentInit
- ngAfterContentChecked
- ngAfterViewInit
- ngAfterViewChecked
- ngOnDestroy
The cycle of Change Detection
We must first comprehend the change detection cycle before moving on to the lifecycle hooks.
The process through which angular keeps the template in sync with the component is called change detection.
Consider the code below.
<div>Hello {{name}}</div>
Constructor
ngOnChanges
@Input() message:string
The data can be sent to the kid by the parent using the property binding method, as demonstrated below.
<app-child [message]="message"> </app-child>
ngOnInit
ngDoCheck
ngAfterContentInit
<h2>Child Component</h2> <ng-content></ng-content> <!-- placehodler for content from parent -->
The content is injected between the opening and closing elements by Parent. This content is passed to the child component by Angular.
<h1>Parent Component</h1> <app-child> This <b>content</b> is injected from parent</app-child>
ngAfterContentChecked
ngAfterViewInit
ngAfterViewChecked
ngOnDestroy
How to Use Lifecycle Hooks
- Hook interfaces for importing data
- Declare Component/Directive to be true. Interface for lifecycle hooks is implemented.
- Make a hook method.
Import Hook interfaces
import { Component,OnInit } from '@angular/core'
Component Implements lifecycle hook interface
export class AppComponent implements OnInit { }
Create the hook method
ngOnInit() { console.log("AppComponent:OnInit"); }
The whole app.component.ts code.
import { Component,OnInit } from '@angular/core'; @Component({ selector: 'app-root', template: ` <h2>Life Cycle Hook</h2>` , styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit { constructor() { console.log("AppComponent:Constructor"); } ngOnInit() { console.log("AppComponent:OnInit"); } }
AppComponent:Constructor AppComponent:OnInit
The Order of Execution of Life Cycle Hooks
- OnChanges
- OnInit
- DoCheck
- AfterContentInit
- AfterContentChecked
- AfterViewInit
- AfterViewChecked
- OnChanges
- DoCheck
- AfterContentChecked
- AfterViewChecked
Angular Lifecycle hook Example
import { ChangeDetectionStrategy, Component, VERSION } from "@angular/core"; @Component({ selector: "my-app", changeDetection:ChangeDetectionStrategy.Default, template: ` <h1>Angular Life Cycle Hooks</h1> Reference : <a href="https://www.tektutorialshub.com/angular/angular-component-life-cycle-hooks/#create-the-hook-method" >Angular Life Cycle Hooks</a > <h1>Root Component</h1> <br /> <input type="text" name="message" [(ngModel)]="message" autocomplete="off" /> <br /> <input type="text" name="content" [(ngModel)]="content" autocomplete="off" /> <br /> hide child : <input type="checkbox" name="hideChild" [(ngModel)]="hideChild" autocomplete="off" /> <br /> <br /> <app-child [message]="message" *ngIf="!hideChild"> <!-- Injected Content --> <b> {{ content }} </b> </app-child> ` }) export class AppComponent { name = "Angular " + VERSION.major; message = "Hello"; content = "Hello"; hideChild=false; constructor() { console.log("AppComponent:Contructed"); } ngOnChanges() { console.log("AppComponent:ngOnChanges"); } ngOnInit() { console.log("AppComponent:ngOnInit"); } ngDoCheck() { console.log("AppComponent:DoCheck"); } ngAfterContentInit() { console.log("AppComponent:ngAfterContentInit"); } ngAfterContentChecked() { console.log("AppComponent:AfterContentChecked"); } ngAfterViewInit() { console.log("AppComponent:AfterViewInit"); } ngAfterViewChecked() { console.log("AppComponent:AfterViewChecked"); } ngOnDestroy() { console.log("AppComponent:ngOnDestroy"); } }
- All hooks are being listened to and logged to the console.
- Message and content are the two form fields. Both are passed to the child component. One is used as an input attribute, while the other is used to project content.
- We can add or delete the ChildComponent from the DOM by using the hideChild form field. The ngIf directive is being used here.
- Property binding is used to pass the message property to ChildComponent.
- Projected content is passed as the content property.
import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core'; import { Customer } from './customer'; @Component({ selector: 'app-child', changeDetection:ChangeDetectionStrategy.Default, template: ` <h2>child component</h2> <br> <!-- Data as a input --> Message from Parent via @input {{message}} <br><br> <!-- Injected Content --> Message from Parent via content injection <ng-content></ng-content> <br><br><br> Code : <input type="text" name="code" [(ngModel)]="customer.code" autocomplete="off"> <br><br> Name: <input type="text" name="name" [(ngModel)]="customer.name" autocomplete="off"> <app-grand-child [customer]="customer"></app-grand-child> ` }) export class ChildComponent { @Input() message:string customer:Customer = new Customer() constructor() { console.log(" ChildComponent:Contructed"); } ngOnChanges() { console.log(" ChildComponent:ngOnChanges"); } ngOnInit() { console.log(" ChildComponent:ngOnInit"); } ngDoCheck() { console.log(" ChildComponent:DoCheck"); } ngAfterContentInit() { console.log(" ChildComponent:ngAfterContentInit"); } ngAfterContentChecked() { console.log(" ChildComponent:AfterContentChecked"); } ngAfterViewInit() { console.log(" ChildComponent:AfterViewInit"); } ngAfterViewChecked() { console.log(" ChildComponent:AfterViewChecked"); } ngOnDestroy() { console.log(" ChildComponent:ngOnDestroy"); } }
- All of the hooks are being listened to.
- The @Input decorator transforms a message into an input property. It will get the information from the parent.
- The placeholder for the projected content from the parent is ng-content>/ng-content>.
- We pass the GrandChildComponent two form fields for the customer object.
import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core'; import { Customer } from './customer'; @Component({ selector: 'app-grand-child', changeDetection:ChangeDetectionStrategy.Default, template: ` <h3>grand child component </h3> <br> Name {{customer.name}} `, }) export class GrandChildComponent { @Input() customer:Customer constructor() { console.log(" GrandChildComponent:Contructed"); } ngOnChanges() { console.log(" GrandChildComponent:ngOnChanges"); } ngOnInit() { console.log(" GrandChildComponent:ngOnInit"); } ngDoCheck() { console.log(" GrandChildComponent:DoCheck"); } ngAfterContentInit() { console.log(" GrandChildComponent:ngAfterContentInit"); } ngAfterContentChecked() { console.log(" GrandChildComponent:AfterContentChecked"); } ngAfterViewInit() { console.log(" GrandChildComponent:AfterViewInit"); } ngAfterViewChecked() { console.log(" GrandChildComponent:AfterViewChecked"); } ngOnDestroy() { console.log(" GrandChildComponent:ngOnDestroy"); } }
- All of the hooks are being listened to.
- The client is marked as an input property via the @Input decorator. It will get the information from the parent.