Angular OnChanges + SimpleChanges Example
October 01, 2021
On this page we will provide Angular OnChanges
and SimpleChanges
example. Angular provides lifecycle hooks for change detection. The OnChanges
is an interface and has a method declaration as ngOnChanges()
. In parent-child component, the child component declares @Input()
property to get values from parent component. Whenever parent component changes the value of properties passed to child component decorated with @Input()
then the method ngOnChanges()
created in child component runs automatically. The method ngOnChanges()
uses SimpleChanges
as an argument that gives new and previous values of input values after changes. In case of input user object data type, ngOnChanges()
is called only when the reference of object is changed in parent component. If we change only values of properties of an input user object, ngOnChanges()
method will not run. In Angular application, OnChanges
can be used for change detection of input properties.
Now find the complete example step-by-step.
Contents
Technologies Used
Find the technologies being used in our example.1. Angular 12.1.0
2. Node.js 12.14.1
3. NPM 7.20.3
Project Structure
Find the project structure of our demo application.angular-demo | |--src | | | |--app | | | | | |--employee.ts | | |--employee.component.ts | | |--employee.component.html | | |--app.component.ts | | |--app.component.html | | |--app.module.ts | | | |--main.ts | |--index.html | |--styles.css | |--node_modules |--package.json
SimpleChange Class and SimpleChanges Interface
SimpleChange
class represents a basic change from a previous to new value. It has following class members. Suppose there is a change in input value, then following property can be used to detect changes.
previousValue: Keeps previous value of input property.
currentValue: Keeps current value of input property.
isFirstChange(): Boolean value that tells whether the new value is the first value assigned.
SimpleChanges
is the interface that represents the changes object for all input property. SimpleChanges
has the key as input property names and values are the instances of SimpleChange
class.
OnChanges
OnChanges
is a lifecycle hook that is called when any data-bound property of a directive changes. OnChanges
is an interface that has a method declaration as follows.
ngOnChanges(changes: SimpleChanges)
OnChanges
interface and override its ngOnChanges()
method. It has the argument as SimpleChanges
that is used to get new and previous values of input property. They are used as follows.
import {Component, OnChanges, SimpleChanges, Input} from '@angular/core'; import { Employee } from './employee'; @Component({ selector: 'app-emp', templateUrl: './employee.component.html' }) export class EmployeeComponent implements OnChanges { @Input() employee = {} as Employee; @Input() message = ''; ngOnChanges(changes: SimpleChanges) { for (let propName in changes) { let change = changes[propName]; let curVal = JSON.stringify(change.currentValue); let prevVal = JSON.stringify(change.previousValue); console.log(curVal); console.log(prevVal); } } }
OnChanges with @Input() Primitive Type
Suppose we have following primitive type decorated with@Input()
in a child component.
@Input() message: string;
ngOnChanges()
method runs. It works for any primitive data type such as string, number etc.
OnChanges with @Input() User Object Type
Suppose we have user object data type decorated with@Input()
in child component.
@Input() employee: Employee;
@Input()
data-bound property, then ngOnChanges()
method is called only when the reference of the object is changed by parent component. Reference of the object can be changed by assigning new object to it. It means if we change value of property of object in parent component, then ngOnChanges()
method will not be called in child component because reference is not changed.
Complete Example
employee.tsexport class Employee { constructor(public name: string, public age: number){} }
import { Component } from '@angular/core'; import { NgForm } from '@angular/forms'; import { Employee } from './employee'; @Component({ selector: 'app-root', templateUrl: './app.component.html' }) export class AppComponent { emp = new Employee('Mahesh', 20); msg: string = 'Hello World!'; onFormSubmit(empForm: NgForm) { let name = empForm.controls['name'].value; let age = empForm.controls['age'].value; this.emp = new Employee(name, age); } }
<div class="employee"> <form #empForm="ngForm" (ngSubmit)="onFormSubmit(empForm)"> <p>Name: <input name="name" [ngModel]="emp.name"></p> <p>Age:<input name="age" [ngModel]="emp.age"></p> <button>Submit</button> </form> </div> <div class="message"> <p>Message: <input [(ngModel)]="msg"/></p> </div> <app-emp [employee]="emp" [message]="msg"></app-emp>
import {Component, OnChanges, SimpleChanges, Input} from '@angular/core'; import { Employee } from './employee'; @Component({ selector: 'app-emp', templateUrl: './employee.component.html' }) export class EmployeeComponent implements OnChanges { @Input() employee = {} as Employee; @Input() message = ''; allMsgChangeLogs: string[] = []; allEmployeeChangeLogs: string[] = []; ngOnChanges(changes: SimpleChanges) { for (let propName in changes) { let change = changes[propName]; let curVal = JSON.stringify(change.currentValue); let prevVal = JSON.stringify(change.previousValue); let changeLog = `${propName}: currentValue = ${curVal}, previousValue = ${prevVal}`; if (propName === 'message') { this.allMsgChangeLogs.push(changeLog); } else if (propName === 'employee') { this.allEmployeeChangeLogs.push(changeLog); } } } }
<div> <b>Employee Change Log</b> <div *ngFor="let changeLog of allEmployeeChangeLogs"> {{changeLog}} </div> </div> <br/><b>Message Change Log</b> <div *ngFor="let changeLog of allMsgChangeLogs"> {{changeLog}} </div>
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; import { AppComponent } from './app.component'; import { EmployeeComponent } from './employee.component'; @NgModule({ imports: [ BrowserModule, FormsModule ], declarations: [ AppComponent, EmployeeComponent ], providers: [ ], bootstrap: [ AppComponent ] }) export class AppModule { }
.employee { background-color: #EEF4F5; width: 350px; } .message { background-color: #EEF4F5; width: 350px; }
Run Application
To run the demo application, find following steps.1. Download source code using download link given below on this page.
2. Use downloaded src in your angular CLI application. To install angular CLI, find the link.
3. Run ng serve using command prompt.
4. Now access the URL http://localhost:4200

References
OnChangesLifecycle hooks
SimpleChange