Component Lifecycle Hooks In Angular 5

Today, I am going to explain what component lifecycle hooks are. Before reading about lifecycle, I suggest you go through the Component and Component and its properties.

COMPONENT LIFECYCLE HOOKS OVERVIEW

Whenever we talk about life cycle we talk about some phases which lie between its birth to its end. Here, I am talking about Component Life Cycle; i.e. a component also goes through many phases after creation until its end. Angular is responsible for maintaining and taking care of all these phases.

After the creation of component, it goes through many phases, but what are our benefits here?  Why we interested in going through this cycle?

The answer is that it’s true that it goes through many phases after creation, but at each stage, you can implement your own code or logic, which helps us a lot.

We can say that once a new component is an instantiation, Angular goes through a couple of different phases in this creation process and it will actually give us a chance to  hook into these phases by implementing some methods as per our requirement.

Angular 5 - LIFECYCLE HOOKS

Lifecycle Sequence

OnChange - OnInit  - DoCheck - AfterContentInit - AfterContentChecked - AfterViewInit - AfterViewChecked - OnDestroy.

Basically, what Angular does with a component is that it creates the component, renders the component, creates and renders the component’s children, checks when the component's data-bound properties change and destroys the component before removing it from the DOM.

Now, try to learn all these hooks and learn how can we put our code between these phases.

We need to learn only 3 steps to use lifecycle hooks, they are:

  • Import Hook interfaces from ‘@angular/core’ library
  • Declare that component/directive implements lifecycle hook interface
  • Create the hook method and define the functionality of that method.

Let's start with these hooks:

ngOnChange()

It is always called whenever one of our bound input changes; i.e., changes occur on those properties which are decorated with @Input() method.

Actually whenever we communicate between parent and child component, then the passing property from parent component is always received by child component with @Input decorator. When the parent changes the Input properties, then this hook is invoked in the child component and we can easily find out the details about which input properties have changed and how they have changed.

Let’s understand with an example.

Create a component called ‘first’ using the below command.

ng g c first

Go to app.component.ts file and write the below code.

  1. @Component({  
  2.   selector: 'app-root',  
  3.   template: `  
  4.               <div class="row">  
  5.                 <div class="col-md-4">  
  6.                   <div class="card">  
  7.                      <div class="card-header bg-success text-white">ngOnChange()</div>  
  8.                      <div class="card-body"><input type="text" [(ngModel)] = "enterValue" /><br/>  
  9.                         <app-first [simpleInput]="enterValue" > </app-first>  
  10.                      </div>  
  11.                   </div>  
  12.                 </div>  
  13.               </div>`,  
  14.   styleUrls: ['./app.component.css']  
  15. })  
  16.   
  17. export class AppComponent {  
  18.   enterValue:string;  
  19.   title = 'app';  
  20. }  

In the above code, we created a textbox and bound it with “enterValue” property (which is defined in AppComponent class as a string).

After that, we use this line.

  1. <app-first [simpleInput]="enterValue" > </app-first>  

We called another component “first” using selector “app-first” (which behaves like a child component for app-component), and bound “enterValue” property of app.component with “simpleInput” using property binding.

If we pass property inside child component, then with the help of @Input Component, we will easily be able to get this property.

Go to first.component.html file, and put the below lines on that file.

  1. <div>  
  2.   You Entered :- {{simpleInput}}  
  3. </div>  

After that, go to first.component.ts file and do the following steps.

  1. Import hook interface, which we want to implement from ‘@angular/core’ library, here we import OnChanges and SimpleChanges like:
    1. import { Component, Input, OnChanges,SimpleChanges } from '@angular/core';  
  1. Declare that Component/directive Implements lifecycle hook interface, like this:
    1. export class FirstComponent implements OnChanges {  
  1. Create the hook method and define the functionality of that method, like this:
    1. @Input() simpleInput:string;  
    2.    ngOnChanges(changes:SimpleChanges){  
    3.       console.log("ON change");  
    4.    }  

In the above code, first we receive the parent’s property called “simpleInput”, with the help of @Input() decorator.

Now, whenever there is a change in this property (simpleInput) , ngOnChanges() are automatically triggered out and print a message on the console. Let’s run the above code and see the output.

Angular 5 - LIFECYCLE HOOKS

Now, we understood that it will run automatically whenever there is a change in the parent’s component property. But I am a little bit confused, why Idid I use this hook() and what is the benefit of it?

So, the answer is that we can easily receive the current and previous value of this property. For this, do the following changes.

In first.component.html file,

  1. <div>  
  2.   You Entered :- {{simpleInput}}  
  3.   <br/> Previous Value :- {{previousValue}}  
  4.   <br> New Value :- {{currentValue}}  
  5. </div>  

In first.component.ts file,

  1. @Input() simpleInput:string;  
  2.   currentValue:string;  
  3.   previousValue:string;  
  4.   
  5.   ngOnChanges(changes:SimpleChanges){  
  6.       console.log("On Change");  
  7.       for(let propertyName in changes){  
  8.       let change=changes[propertyName];  
  9.       let current=JSON.stringify(change.currentValue);  
  10.       this.currentValue=change.currentValue;  
  11.       let previous=JSON.stringify(change.previousValue);  
  12.       this.previousValue=change.previousValue;  
  13.       console.log(propertyName + ':current value :- ' +current+' :previous value :- '+previous);  
  14.     }  
  15.   }  

In the above code, all changes have come into “changes” which is the object of “SimpleChanges”. A changes object whose keys are property names and values are instances of SimpleChange. Now we can easily get old and new values of that property. Let’s see what we will get after running this code:

Angular 5 - LIFECYCLE HOOKS

ngOnInit()

ngOnInit() this methods can be executed once component has been initialized, i.e. whenever component is created it triggers it. This hook is fired after ngOnChanges() and before any of the child directive properties are initialized. There is a place where we will put logic related to initialization of properties.

For better understanding of this, we change our first.component.ts page a little bit, we just import, implement, and add the ngOnInit() definition like,

  1. ngOnInit(){  
  2.     console.log("ngOnInit hook called");  
  3.     this.currentValue="Mahesh";  
  4.     this.previousValue="Verma";  
  5.   }  

In the above lines, we are trying to initialize the value of some properties in ngOnIt() which trigger after ngOnChanges(), look at the output of the above code.

Angular 5 - LIFECYCLE HOOKS

If we enter any value in a textbox then it changes the parent’s component value, and whenever the parent component's value changes, then ngOnChanges() fires, but at this time, ngOnInit() doesn't fire. This shows that ngOnChanges() fires whenever property will change, however, ngOnInit() runs only once at the time of component initialization.

ngDoCheck()

Whenever something changes on the template of a component or inside the component then ngDoCheck() executes. We can also say that it is called during every change detection run. This hook is called  after ngOnInit().

Actually, this is very similar to ngOnChanges() hook, the major difference is that ngOnChanges() does not detect all the changes made to the input properties. It detects changes for those properties which are passed by value. However, ngDoCheck() detects changes for those properties also which are passed by reference such as arrays. Let’s understand with an example:

Go to the app.component.ts file, and put the below code.

  1. @Component({  
  2.   selector: 'app-root',  
  3.   template: `  
  4.               <div class="row">  
  5.                 <div class="col-md-4">  
  6.                   <div class="card">  
  7.                      <div class="card-header bg-primary text-white">ngOnChange() vs ngDoCheck()</div>  
  8.                      <div class="card-body">  
  9.                        <input type="text" [(ngModel)] = "enterValue" /><br/>  
  10.                        <app-first [simpleInput]="enterValue" [arrList] = "myArr"></app-first>   
  11.                        <button class='btn btn-primary' (click)="addValue()"> Add </button>     
  12.                      </div>  
  13.                   </div>  
  14.                 </div>  
  15.               </div>`,  
  16.   styleUrls: ['./app.component.css']  
  17. })  

In above code, we pass an array list (arrList) to the child component, i.e., first component and called a method “addValue()” on click event of button. 

  1. export class AppComponent {  ,
  2.   enterValue:string;  
  3.   myArr: any = ['C''C++''C#'];  
  4.   addValue() {  
  5.     this.myArr.push("Java");  
  6.     }  
  7. }  

Now, we go to first.component.html file and place the below code.

  1. <div>  
  2.   You Entered :- {{simpleInput}}  
  3. </div>  
  4. <div>  
  5.   <span>Array List (Pass by Parent's Component)</span><br>  
  6.   <span *ngFor="let record of arrList">{{record}}<br></span>  
  7. </div>  

Go to first.component.ts file, in this, add arrList property with @Input decorator and ngDoCheck() method like this:

  1. @Input() arrList:any=[];  
  2.   
  3. ngDoCheck(){  
  4.     console.log("ngDoCheck hook called");  
  5. }  
Angular 5 - LIFECYCLE HOOKS

Along with this article, I have attached a sample project where you will find all the hooks with implementation. 

Conclusion

As we know, components are very important in Angular and as a developer, we should know about these hooks also. After reading this article, we can say that we have knowledge of some lifecycle hooks like OnChanges, OnInit, DoCheck.

I will explain the remaining lifecycle hooks in my next articles, Component Lifecycle Hooks in Angular 5 Part 2.