Angular ngOnChanges life Cycle Hook

In this article, we are going to look at how ngOnChanges Life cycle hook works in Angular.  ngOnChanges or OnChanges event fired when the Angular detects changes to the @Input properties of the Component.  It gets the changes in the form of simplechanges object. We will be learning all these in this tutorial

What is nOnChanges Life cycle hook

The ngOnChnages is a life cycle hook, which angular fires when it detects changes to data bound input property. This method receives a SimpeChanges object, which contains the current and previous property values.

There are several ways parent component can communicate with the child component. One of the ways is to use the @Input decorator. We looked at this in our tutorial passing data to Child Components

Let us just recap what we have done in that tutorial

The child Component decorates the property as a @Input annotation.

And then parent passes the data to the child component using property binding as shown below

Whenever the parent changes the value of the message property,  the Angular raises the OnChanges hook event in the child component, so that it can act upon it.

How does it work

The ngOnChanges() method takes an object that maps each changed property name to a SimpleChange object, which holds the current and previous property values. You can iterate over the changed properties and act upon it.

SimpleChange

SimpleChange is a simple class, which has three properties

Property NameDescription
previousValue:anyPrevious value of the input property.
currentValue:anyNew or current value of the input property.
FirstChange():booleanBoolean value, which tells us whether it was the first time the change has taken place

SimpleChanges

The every @Input property of our component gets a SimpleChange object (if Property is changed)

SimpleChanges is the object that contains the instance of all those SimpleChange objects. You can access those SimpleChange objects using the name of the @Input property as key

For Example, if the two @Input properties message1 & message2 as changed, then the SimpleChanges object looks like

And if the input property is an object (customer object with name & code property) then the SimpleChanges would be

ngOnChanges example

Create a class customer.ts under src/app folder.

Parent Component

Lets us look at the code

We have 3 user input fields for the message , code, and name. The UpdateCustomer button updates the Customer object,

The message and Customer is bound to the child component using the @Import annotation

The AppComponent class has a message & customer property. The Customer property is updated with new code & name when the updateCustomer button is clicked

Child Component

Let us look at each line of code in detail

First, We imported the Input, OnInit, OnChanges, SimpleChanges, SimpleChange from Angular Core

The Template displays the message and the code & name property from the customer object. Both these properties are updated from the parent component

We also display the changelog using ngFor Directive.

The child Component implements the OnChanges & OnInit life cycle hooks.

The OnInit hook

The ngOnChnages hook gets all the Changes as an instance of SimpleChanges. This object contains the instance of SimpleChange for each property

We, then loop through each property of the SimpleChanges object and get a reference to the SimpleChange object.

Next, we will take the current & previous value of each property and add it to change log

That’s it.

Now our OnChanges hook is ready to use

Now, run the code and type the Hello and you will see the following log

Open the developer console and you should see the changes object

Note that the first OnChanges fired before the OnInit hook. This ensures that initial values bound to inputs are available when ngOnInit() is called

OnChanges does not fire always

Now, change the customer code and name and click UpdateCustomer button.

The Child Components displays new customer code & Name, but OnChanges event does not fire.

This behavior is by design

The Angular uses dirty checking (===) for detecting changes in the input properties. For primitive data types like string, the above comparison works perfectly

But in case of objects like customer, this fails. For Arrays/objects, the dirty checking means that only the references are checked. Since the reference to the customer stays the same the Angular does not raise the OnChanges hook

That leaves us two possible solutions

  1. Create a new customer and copy the old data to new customer
  2. We can Perform our own change detection using the ngDoCheck lifecycle hook

Update the updateCustomer method and create a new instance of customer every time

Now, run the code, you will see onChanges event fired when customer is updated

The second method is to use the ngDoCheck lifecycle hook, which we will cover in the next tutorial

Conclusion

In this tutorial, we learned how to use ngOnChanges method. We learned how to find out which properties are changed using SimpleChanges object

Leave a Comment

Your email address will not be published.

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

Scroll to Top