Angular ngOnChanges Lifecycle Hook

The ngOnChanges() is a built-in Angular callback method invoked immediately after the default change detector checks data-bound properties if at least one has changed. Before the view and content, children are checked.

Example

interface OnChanges {
  ngOnChanges(changes: SimpleChanges): void
}

Angular, by default, comes with AppComponent. Therefore, it will act as a parent component.

Let’s create one more component called ChildComponent.

Now we have two components.

  1. AppComponent: Parent Component
  2. ChildComponent: Child Component

We define a property inside the Parent component and pass it to the Child component, which will accept that property using the @Input directive.

We modify the value of the property from the Parent and Child component.

Write the following code inside the app.component.ts file.

// app.component.ts

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  data = 0;
  constructor() {
  }

  ngOnInit(): void {
  }

  changeFromParent(): void {
    this.data += 1;
  }
}

We are defining a class property called data whose initial value is 0.

Then we have defined a function called changeFromParent(), called when the button is clicked.

After clicking the button, the property’s value will be modified, adding +1.

Write the following code inside the app.component.html file.

<!-- app.component.html -->

<div class="container">
  <div class="row">
    <div class="col-md-4">
      <a (click)="changeFromParent()" class="btn btn-success">Change from parent</a>
    </div>
    <div class="col-md-8">
      <app-child [parentData]=data></app-child>
    </div>
  </div>
</div>

We have used Bootstrap 4 for styling our components.

In this code, we have defined a click event, and if it is fired, then the data property will be incremented by one, and it is defined inside the parent component.

We have also defined a Child component that accepts the parentData as input data from the Parent component.

Write the following code inside the child.component.ts file.

// child.component.ts

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

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit, OnChanges {

  @Input() parentData: any;

  constructor() { }

  ngOnInit(): void {
  }

  changeFromChild(): void {
    this.parentData -= 1;
  }

  ngOnChanges(changes: SimpleChanges): void {
    console.log(changes);
  }

}

We defined the @Input property, indicating we have input data from the parent component.

Then we have defined two methods.

  1. changeFromChild()
  2. ngOnChanges()

The changeFromChild() is a method that will be called when we click a link from the child component, just like we have defined inside the app.component.ts file.

The ngOnChanges() method will be invoked when we change the data property from the parent component. It will log the changes object whose format is the following.

  1. previousValue
  2. currentValue
  3. firstChange (true the first time ngOnChanges is called)

The SimpleChanges instance looks like the following.

class SimpleChange {
  constructor(previousValue: any, currentValue: any, firstChange: boolean)
  previousValue: any
  currentValue: any
  firstChange: boolean
  isFirstChange(): boolean
}

Every time ngOnChanges() is called, the SimpleChanges instance captures the parentData.

The changeFromChild() won’t call ngOnChanges().

The changeFromParent() will call ngOnChanges().

When ngOnChanges() is called, this example logs the SimpleChanges instance.

That’s it!

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.