Angular Series Part 2 From Basics to Advanced: Exploring Angular’s ngOnChanges

chintanonweb - May 29 - - Dev Community

Understanding Angular's ngOnChanges: A Comprehensive Guide

Introduction

Angular, a powerful front-end framework, offers numerous lifecycle hooks to manage component behavior. Among these hooks, ngOnChanges is particularly important as it allows developers to react to changes in component input properties. Understanding how to use ngOnChanges effectively can significantly improve the efficiency and performance of Angular applications. This article will dive deep into the ngOnChanges lifecycle hook, providing step-by-step examples and covering various scenarios to ensure a thorough grasp of its usage.

What Is ngOnChanges?

ngOnChanges is a lifecycle hook in Angular that is called whenever there are changes to input properties of a component. It allows you to act upon those changes and is useful for tasks that need to be executed when input values change.

How Does ngOnChanges Work?

The ngOnChanges method is triggered when Angular sets or resets data-bound input properties. It receives a SimpleChanges object, which contains the current and previous values of the input properties.

Syntax

ngOnChanges(changes: SimpleChanges): void {
  // logic to handle changes
}
Enter fullscreen mode Exit fullscreen mode

Setting Up an Angular Project

Before diving into ngOnChanges, let's set up a basic Angular project. This will help us to follow along with the examples.

Step 1: Create a New Angular Project

Run the following command to create a new Angular project:

ng new ngOnChangesDemo
cd ngOnChangesDemo
Enter fullscreen mode Exit fullscreen mode

Step 2: Generate a New Component

Generate a new component that we'll use to demonstrate ngOnChanges:

ng generate component demo
Enter fullscreen mode Exit fullscreen mode

Implementing ngOnChanges

Let's implement ngOnChanges in our newly created component to see how it works in practice.

Example 1: Basic Usage of ngOnChanges

First, let's set up a parent component that will pass data to the DemoComponent.

Parent Component Template (app.component.html)

<app-demo [inputValue]="parentValue"></app-demo>
<button (click)="changeValue()">Change Value</button>
Enter fullscreen mode Exit fullscreen mode

Parent Component Class (app.component.ts)

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

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

  changeValue() {
    this.parentValue = Math.floor(Math.random() * 100);
  }
}
Enter fullscreen mode Exit fullscreen mode

Child Component Template (demo.component.html)

<p>Input Value: {{ inputValue }}</p>
Enter fullscreen mode Exit fullscreen mode

Child Component Class (demo.component.ts)

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

@Component({
  selector: 'app-demo',
  templateUrl: './demo.component.html',
  styleUrls: ['./demo.component.css']
})
export class DemoComponent implements OnChanges {
  @Input() inputValue: number;

  ngOnChanges(changes: SimpleChanges) {
    for (let propName in changes) {
      let change = changes[propName];
      let cur = JSON.stringify(change.currentValue);
      let prev = JSON.stringify(change.previousValue);
      console.log(`${propName}: currentValue = ${cur}, previousValue = ${prev}`);
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Explanation

In this example:

  • DemoComponent receives an input property inputValue.
  • Whenever inputValue changes, the ngOnChanges method logs the current and previous values to the console.
  • The parent component (AppComponent) has a button to change parentValue, demonstrating how ngOnChanges responds to changes in input properties.

Example 2: Handling Multiple Input Properties

Let's extend the example to handle multiple input properties.

Parent Component Template (app.component.html)

<app-demo [inputValue]="parentValue" [anotherValue]="parentAnotherValue"></app-demo>
<button (click)="changeValue()">Change Values</button>
Enter fullscreen mode Exit fullscreen mode

Parent Component Class (app.component.ts)

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  parentValue: number = 0;
  parentAnotherValue: string = 'Initial Value';

  changeValue() {
    this.parentValue = Math.floor(Math.random() * 100);
    this.parentAnotherValue = 'Changed Value ' + Math.floor(Math.random() * 100);
  }
}
Enter fullscreen mode Exit fullscreen mode

Child Component Template (demo.component.html)

<p>Input Value: {{ inputValue }}</p>
<p>Another Value: {{ anotherValue }}</p>
Enter fullscreen mode Exit fullscreen mode

Child Component Class (demo.component.ts)

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

@Component({
  selector: 'app-demo',
  templateUrl: './demo.component.html',
  styleUrls: ['./demo.component.css']
})
export class DemoComponent implements OnChanges {
  @Input() inputValue: number;
  @Input() anotherValue: string;

  ngOnChanges(changes: SimpleChanges) {
    for (let propName in changes) {
      let change = changes[propName];
      let cur = JSON.stringify(change.currentValue);
      let prev = JSON.stringify(change.previousValue);
      console.log(`${propName}: currentValue = ${cur}, previousValue = ${prev}`);
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Explanation

In this extended example:

  • DemoComponent now has two input properties: inputValue and anotherValue.
  • The ngOnChanges method logs changes to both properties.
  • The parent component (AppComponent) changes both input values when the button is clicked, showcasing how ngOnChanges handles multiple property changes.

Common Scenarios and Best Practices

Scenario 1: Initial Value Setting

ngOnChanges is also called when the component is initialized if there are any input properties.

Example

If the parent component initially sets values for the inputs:

<app-demo [inputValue]="42" [anotherValue]="'Hello'"></app-demo>
Enter fullscreen mode Exit fullscreen mode

ngOnChanges will log these initial values when the component is first rendered.

Scenario 2: Ignoring Unnecessary Changes

In some cases, you might want to ignore certain changes or perform actions only on specific changes.

Example

ngOnChanges(changes: SimpleChanges) {
  if (changes['inputValue']) {
    let cur = JSON.stringify(changes['inputValue'].currentValue);
    let prev = JSON.stringify(changes['inputValue'].previousValue);
    console.log(`inputValue: currentValue = ${cur}, previousValue = ${prev}`);
  }
}
Enter fullscreen mode Exit fullscreen mode

Scenario 3: Deep Change Detection

ngOnChanges performs shallow comparison. For deep objects, additional logic is required.

Example

import { isEqual } from 'lodash';

ngOnChanges(changes: SimpleChanges) {
  if (changes['complexObject']) {
    let cur = changes['complexObject'].currentValue;
    let prev = changes['complexObject'].previousValue;
    if (!isEqual(cur, prev)) {
      console.log(`complexObject has changed.`);
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Best Practices

  1. Minimize Heavy Processing: Avoid performing heavy computations in ngOnChanges. Delegate them to other methods if necessary.
  2. Use Immutable Data Structures: This helps in efficiently detecting changes.
  3. Combine with Other Lifecycle Hooks: Use ngOnInit and ngDoCheck for initialization and custom change detection logic.

FAQ Section

What Is ngOnChanges Used For?

ngOnChanges is used to detect and respond to changes in input properties of a component. It is essential for tasks that need to react to input value changes dynamically.

When Is ngOnChanges Called?

ngOnChanges is called before ngOnInit when the component is initialized and whenever any data-bound input properties change.

How Does ngOnChanges Differ from ngDoCheck?

ngOnChanges is triggered automatically by Angular when input properties change, while ngDoCheck is called during every change detection cycle and can be used for custom change detection.

Can ngOnChanges Be Used with All Input Properties?

Yes, ngOnChanges can be used with all input properties defined with the @Input decorator.

What Is SimpleChanges?

SimpleChanges is an object that contains the current and previous values of the input properties. It is passed as an argument to the ngOnChanges method.

Conclusion

Mastering ngOnChanges is crucial for developing dynamic and responsive Angular applications. By understanding its usage, handling multiple input properties, and applying best practices, developers can effectively manage component behavior based on changing inputs. This comprehensive guide provides the foundation needed to utilize ngOnChanges proficiently in your Angular projects.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .