Developer Snippet Diary

Angular Life Cycle Hooks | ngOnChanges??, ngOnInit, ngDoCheck, ngAfterContent??, ngAfterViewInit, ngOnDestroy | Angular 15+

Angular provides lifecycle hooks that allow you to tap into specific moments in the lifecycle of a component or directive. By implementing these hooks in your code, you can execute custom logic at various stages of a component's life, from its creation to its destruction.

The Angular lifecycle hooks are the methods that angular invokes on the directives and components as it creates, changes, and destroys them.

When the angular applicationstarts, it first creates and renders the root component. Then, it creates and renders its Children's & their children. It forms a tree of components
Once Angular loads the components, it starts the process of rendering the view. To do that, it needs to check the input properties, evaluate the data bindings & expressions, render the projected content etc.

Angular lets us know when these events happen using lifecycle hooks. For Example:

  • ngonInit when Angular initializes the component for the first time. ngoninit is life cycle hook
  • When a component's input property change, Angular invokes ngonChanges
  • If the component is destroyed, Angular invokes ngonDestroy

Change detection cycle

<div>Hello {{name}}</div>

for example let's say in the view template of our component we have this div and inside this div we are using the name property of the component class now angular will update the dom every time the value of this name property will change and it does it instantly now the question is how does angular will know when the value of this name property will change it does so by running a change detection cycle on every event that may result in a change in dom

Projected content: Projected content is that HIML content which replaces the <ng-content directive in child component. ie h5 is projected content

<app-single-product>
	<h5 class="card-title">Card title 1</h5>
</app-single-product>

Input bound properties: These are those properties of a component class which is decorated with @Input () decorator.

Construtor of component:

  • Life Cycle of a component begins, when Angular creates the component class. First method that gets invoked is class Constructor.
  • Constructor is neither a life cycle hook nor it is specific to Angular. It is a JavaScript feature. It is a method which gets invoked, when a class is created.
  • When a constructor is called, at that point, none of the components input properties are updated and available to use. Neither its child components are constructed.
  • Projected contents are also not available. Once Angular instantiates the class, it kick-start the first change detection cycle of the component.

 ngOnChanges 

This hook is called when Angular detects changes to input properties. It receives an object containing the previous and current values of the changed properties. It is called even before ngOnInit for the first time.

ngOnChanges(changes: SimpleChanges) { /* custom logic */ }
  • It is executed right at the start, when a new component is created, and it also gets executed whenever one of the bound input property changes.
  • Angular invokes ngonChanges life cycle hook whenever any data bound input property of the component or directive changes.
  • Input properties are those properties, which we define using the @Input decorator. It is one of the ways by which a parent component communicates with the child component.
  • Initializing the Input properties is the first task that angular carries during the change detection cycle. And if it detects any change in input property, then it raises the ngOnChanges hook. It does so during every change detection cycle.
  • This hook is not raised if change detection doeSnotdetect any changes
//parent.component.ts
import { Component, OnInit } from '@angular/core';
@Component({
  selector: 'app-parent',
  template: `
    <app-child [message]="parentMessage"></app-child>
    <button (click)="changeMessage()">Change Message</button>
  `,
  styleUrls: ['./parent.component.css']
})
export class ParentComponent {
  parentMessage = 'Initial message';
  changeMessage() {
    this.parentMessage = 'Updated message';
  }
}
//child.component.ts
import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
@Component({
  selector: 'app-child',
  template: `
    <p>Current message: {{ message }}</p>
  `,
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnChanges {
  @Input() message: string;
  ngOnChanges(changes: SimpleChanges) {
    if (changes['message']) {
      console.log('Previous message:', changes['message'].previousValue);
      console.log('Current message:', changes['message'].currentValue);
    }
  }
}

ngOnInit

This hook is called once after the component is initialized, and it's a good place to perform any initial setup, like fetching data or setting default values for properties. It is called after the first ngOnChanges.

ngOnInit() { /* custom logic */ }
  • Angular raises the ngonInit hook, after it creates the component and updates its input properties.
  • This hook is fired only once and immediately after its creation (during the first change detection)
  • This is a perfect place where you want to add any initialization logic for your component.
  • Here you have access to every input property of the component. You can use them in http get requests to get the data from the back-end server or run some initialization logic etc.
  • But remember that, by the time ngOnlnit get's called, none of the child components or projected content are available at this point. Hence any properties we decorate with @ViewChild, @ViewChildren, @ContentChild &@contentChildren will not be available to use.
import { Component, OnInit } from '@angular/core';
@Component({
  selector: 'app-example',
  template: `
    <h1>{{ title }}</h1>
    <p>{{ description }}</p>
  `,
})
export class ExampleComponent implements OnInit {
  title: string;
  description: string;
  ngOnInit() {
    this.title = 'Welcome to ngOnInit Example';
    this.description = 'This content is initialized in the ngOnInit lifecycle hook.';
  }
}

ngDoCheck

This hook is called whenever Angular's change detection runs. It allows you to implement your custom change detection logic if needed. Be cautious when using this hook, as it can have performance implications if the logic is too complex.

ngDoCheck() { /* custom logic */ }
  • The Angular invokes the ngDoCheck hook event during every change detection cycle. This hook is invoked even if there is no change in any of the properties.For example, ngDoCheck will run if you clicked a button on the webpage which does not change anything. But still, it's an event.
  • Angular invokes ngDoCheck it after the ngonChanges & ngonInit hooks.
  • You can use this hook to Implement a custom change detection, whenever Angular fails to detect the changes made to Input properties
  • ngDoCheck is also a great method to use, when you want to execute some code on every change detection cycle.

ngAfterContentInit

This hook is called once after Angular has projected external content (using ng-content) into the component's view. It is useful for manipulating or interacting with projected content.

ngAfterContentInit() { /* custom logic */ }
  • ngAfterContentInit Life cycle hook is called after the Component's projected content has been fully initialized.
  • Angular also updates the properties decorated with the @ContentChild and @ContentChildren before raising this hook. This hook is also raised, even if there is no content to project.
  • The content here refers to the external content injected from the parent component via Content Projection
  • The Angular Components can include the ng-content element, which acts as a placeholder for the content from the parent. Parent injects the content between the opening& closing selector element. Angular passes this content to the child component

ngAfterContentChecked

  • ngAfterContentChecked Life cycle hook is called during every change detection cycle after Angular finishes checking of component's projected content
  • Angular also updates the properties decorated with the @ContentChild and@ContentChildren before raising this hook. Angular calls this hook even if there is no projected content in the component.
  • This hook is very similar to the ngAfterContentInit hook. Both are called after the external content is initialized, checked & updated.
  • Only difference is that ngAfterContentChecked is raised after every change detection cycle. While ngAfterContentInit during the first change detection cycle.

ngAfterContentChecked

This hook is called after Angular has checked the projected content (using ng-content) and performed change detection. It is called after each ngDoCheck.

ngAfterContentChecked() { /* custom logic */ }

ngAfterViewInit

This hook is called once after Angular has initialized the component's view and child views (or the view of a directive). It's an ideal place to interact with the DOM or child components.

ngAfterViewInit() { /* custom logic */ }
  • ngAfterViewInit hook is called after the Component's View & allits child views are fully initialized. Angular also updates the properties decorated with the @ViewChild & @ViewChildren properties before raising this hook.
  • The View here refers to the view template of the current component and all its child components & directives.
  • This hook is called during the first change detection cycle, where angular initializes the view for the first time
  • At this point all the lifecycle hook methods& change detection of all child components & directives are processed& Component is completely ready
  • This is a component only hook.

ngAfterViewInitCheck

This hook is called after Angular has checked the component's view and child views (or the view of a directive) and performed change detection. It is called after each ngAfterContentChecked.

ngAfterViewChecked() { /* custom logic */ }
  • The Angular fires this hook after it checks & updates the component's views and child views. This event is fired after the ngAfterViewInit and after that during every change detection cycle.
  • This hook is very similar to the ngAfterViewInit hook. Both are called after all the child components & directives are initialized and updated
  • Only difference is that ngAfterViewChecked is raised during every change detection cycle. While ngAfterViewInit is raised during the first change detection cycle
  • This is a component only hook.

ngOnDestroy

This hook is called just before Angular destroys the component or directive. It's a great place to perform cleanup tasks, such as unsubscribing from observables or detaching event listeners.

ngOnDestroy() { /* custom logic */ }
  • If you destroy a component, for example, when you placed ngIf ona component, and this ngIf then set to false, at that time, ngIf will remove that component from the DOM, at that time, ngOnDestroy is called
  • This method is the great place to do some cleanup work, because this is called right before the objects will be destroyed itself by angular
  • This is the correct place where you would like to Unsubscribe Observables and detach event handlers to avoid memory leaks.

Example:

import { Component,Input,OnChanges, OnInit, SimpleChanges,AfterContentInit } from '@angular/core';

@Component({
  selector: 'app-demo',
  templateUrl: './demo.component.html',
  styleUrls: ['./demo.component.css']
})
export class DemoComponent implements AfterContentInit,OnChanges, OnInit{
  @Input() value:string="demo";

  constructor(){
    console.log("I AM CONSTRUCTOR");
  }
  ngAfterContentInit() {
    console.log("ngAfterContentInit");
  }
  ngOnChanges(change:SimpleChanges){
    console.log(change);
  }
  ngOnInit(){
    console.log("ngOnInit");
  }
  ngDoCheck(){
    console.log("docehck");
  }
}
Posted by: R GONDAL
Email: rizikmw@gmail.com