Angular @input Check Which Property Changed using OnChanges

Using @Input decorator parent component can pass values to child components using property binding. But there may be a case where we are passing more than one property in a child component.

We may need control on which property is changed and also check if other properties have changed from the previous one or not.

In this tutorial, we will discuss how to check which of the passed input properties changed by using the OnChanges lifecycle hook of a component.

Here we have a parent component with two buttons to add scores of two teams. The child component TeamScoresComponent will display the updated latest scores with all progress of the match.

Child Component

In the terminal window run following command to create a child component TeamScoresComponent

$ ng generate component components/team-scores

In the team-scores.component.html file place following HTML template

<h1>Team Score Card</h1>


<h3>Team A: {{teamA}}</h3>
<h3>Team B: {{teamB}}</h3>

<h4>Match Progress:</h4>
<ul>
      <li *ngFor="let progress of matchProgress">{{progress}}</li>
</ul>

The matchProgress will keep the progress of match as an array. The teamA and teamB variables will show updated scores.

In the team-scores.component.ts class file place following code

// team-scores.components.ts
import { Component, Input, OnChanges, SimpleChange } from '@angular/core';

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

  @Input() teamA: number;
  @Input() teamB: number;

  matchProgress: string[] = [];

  constructor() { }

  ngOnChanges(changes: { [propKey: string]: SimpleChange }) {
    console.log(JSON.stringify(changes));

    let log: string[] = [];
    for (let propName in changes) {
      let changedProp = changes[propName];
      let to = JSON.stringify(changedProp.currentValue);
      if (changedProp.isFirstChange()) {
        log.push(`Game started with score of ${propName} set to ${to}`);
      } else {
        let from = JSON.stringify(changedProp.previousValue);
        log.push(`${propName} scores increased from ${from} to ${to}`);
      }
    }
    this.matchProgress.push(log.join(', '));
  }

}

The ngOnChanges method is called on child component load and whenever a value is passed via Input properties which are teamA and teamB here.

Using the SimpleChange class type we can fetch the properties which are changed and also the value of the previous and current instance.

Parent Component

Now we will add the app-team-scores component in App component with teamA and teamB input properties.

There are two buttons to update the scores of each team.

In the app.component.html file add following code

<h2>Source code version</h2>

<button (click)="addTeamA()">+ Team A Score</button>
<button (click)="addTeamB()">+ Team B Score</button>

<app-team-scores [teamA]="teamA" [teamB]="teamB"></app-team-scores>

In app.component.ts class, file add following code

// app.component.ts
import { Component } from '@angular/core';

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

  teamA = 0;
  teamB = 0;

  addTeamA() {
    this.teamA++;
  }

  addTeamB() {
    this.teamB++;
  }

}

 

Leave a Comment

Your email address will not be published. Required fields are marked *