What is ngOnChanges in Angular 18?

What is ngOnChanges in Angular 18?

Introduction

In today’s post, we’re diving into one of Angular's most fascinating lifecycle hooks—ngOnChanges. If you've been using Angular for a while or you're just beginning to master component lifecycle hooks, understanding ngOnChanges is key to making your applications smarter and more efficient.

Have you ever wondered how to react to changes in your component's inputs and what happens under the hood in Angular 18? Stick around, because by the end of this article, you'll know exactly how to leverage ngOnChanges to make your components more dynamic and responsive!

What is ngOnChanges?

ngOnChanges is a lifecycle hook in Angular that gets called whenever there is a change to one of the component's input properties. This hook is perfect for scenarios where you need to perform an action whenever an @Input property changes. It is particularly useful in child components that rely on updated data from a parent component.

Let’s walk through an example step-by-step to understand how ngOnChanges works and why it is so important.

Creating a Child Component with ngOnChanges

To get started, let’s create a new component called ChildComponent. We will build it gradually and implement ngOnChanges to see it in action.

First, we need to import the necessary modules. Let’s import ComponentInputOnChanges, and SimpleChanges from @angular/core:

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

Next, we’ll define our ChildComponent by adding a selector, a simple template, and a style URL:

@Component({
  selector: 'app-child',
  template: `<p>{{data}}</p>`,
  styleUrls: ['./child.component.css']
})
1@Component({ 2 selector: 'app-child', 3 template: `<p>{{data}}</p>`, 4 styleUrls: ['./child.component.css'] 5})

Now, let’s create the ChildComponent class. We want this component to receive data from a parent component, so we’ll add an @Input() property called data and initialize it with an empty string:

export class ChildComponent {
  @Input() data: string = '';
}
1export class ChildComponent { 2 @Input() data: string = ''; 3}
Adding ngOnChanges to React to Input Changes

At this point, we have a basic ChildComponent that accepts an @Input() called data. But what if we want to react whenever data changes? That’s where ngOnChanges comes in. Let’s implement ngOnChanges() to see how it works.

export class ChildComponent implements OnChanges {
  @Input() data: string = '';

  ngOnChanges(changes: SimpleChanges) {
    console.log('Changes detected:', changes);
  }
}
1export class ChildComponent implements OnChanges { 2 @Input() data: string = ''; 3 4 ngOnChanges(changes: SimpleChanges) { 5 console.log('Changes detected:', changes); 6 } 7}


With
ngOnChanges added to our component, this lifecycle hook will get triggered whenever the data input changes. The changes parameter, which is of type SimpleChanges, provides details about what has changed in our input properties.

Understanding SimpleChanges

So, what exactly is SimpleChanges and why did we use it here as the type for the changes parameter? SimpleChanges is an object that contains information about each changed property, including details like the previous valuecurrent value, and whether it's the first change. By using SimpleChanges, we gain a type-safe method to understand how our input properties are evolving. This helps us write robust and maintainable code.

Here's a quick example to illustrate its usefulness:

ngOnChanges(changes: SimpleChanges) {
  if (changes['data'] && !changes['data'].isFirstChange()) {
    console.log('Previous value:', changes['data'].previousValue);
    console.log('Current value:', changes['data'].currentValue);
  }
}
1ngOnChanges(changes: SimpleChanges) { 2 if (changes['data'] && !changes['data'].isFirstChange()) { 3 console.log('Previous value:', changes['data'].previousValue); 4 console.log('Current value:', changes['data'].currentValue); 5 } 6}


In this example,
SimpleChanges helps ensure type safety by providing well-defined properties, such as previousValue and currentValue, and allowing us to check if it’s the first change using isFirstChange(). This type safety helps prevent runtime errors and makes the code more predictable and easier to maintain.

Parent Component Example

To see ngOnChanges in action, let’s modify the data property from the parent component. In the ParentComponent, let’s add a button that modifies the data we pass to ChildComponent:

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

@Component({
  selector: 'app-parent',
  template: `
    <button (click)="changeData()">Change Data</button>
    <app-child [data]="parentData"></app-child>
  `,
  styleUrls: ['./parent.component.css']
})
export class ParentComponent {
  parentData: string = 'Initial Data';

  changeData() {
    this.parentData = 'Updated Data at ' + new Date().toLocaleTimeString();
  }
}
1import { Component } from '@angular/core'; 2 3@Component({ 4 selector: 'app-parent', 5 template: ` 6 <button (click)="changeData()">Change Data</button> 7 <app-child [data]="parentData"></app-child> 8 `, 9 styleUrls: ['./parent.component.css'] 10}) 11export class ParentComponent { 12 parentData: string = 'Initial Data'; 13 14 changeData() { 15 this.parentData = 'Updated Data at ' + new Date().toLocaleTimeString(); 16 } 17}

Every time we click the button, parentData changes, which means ngOnChanges in ChildComponent gets triggered. In the console, you will see that the ngOnChanges hook logs the changes every time we click the button. The SimpleChanges object gives us valuable information, like the previous valuecurrent value, and whether it is the first change.

Why Does This Matter?

There are a few common use cases for ngOnChanges:

  1. Data Validation: You can validate incoming data before using it in your component.
  2. Conditional Logic: Perform different actions depending on how the data has changed, such as resetting component states.
  3. Triggering External Processes: Start an animation or make a service call when data updates.

Summary

In this post, we took a deep dive into ngOnChanges in Angular 18. Hopefully, you can now see how powerful and useful this lifecycle hook can be in your projects. By understanding SimpleChanges and the lifecycle of your components, you can make your Angular applications more efficient and responsive to changes.

Have you ever faced a scenario where you needed to respond to input changes dynamically? Drop a comment below and share your experiences. We’d love to hear how you’ve solved those challenges!

If you found this article helpful, don’t forget to share it with your fellow developers. Also, feel free to leave feedback or suggestions for future topics—I’d be happy to cover more Angular concepts that interest you.

Keep coding and stay awesome!