Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why ngOnChanges is not running in this case? (Angular Docs Example)

I’m learning angular and I run into this ngOnChanges example from Angular docs (stackblitz) :

on-changes-parent.component.html

<h2>{{title}}</h2>
<label for="power-input">Power: </label>
<input type="text" id="power-input" [(ngModel)]="power">
<label for="hero-name"> Hero.name: </label>
<input type="text" id="hero-name" [(ngModel)]="hero.name">

<button type="button" (click)="reset()">Reset Log</button>

<on-changes [hero]="hero" [power]="power"></on-changes>

on-changes-parent.component.html

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

export class OnChangesParentComponent {
  hero!: Hero;
  power = '';
  title = 'OnChanges';
  @ViewChild(OnChangesComponent) childView!: OnChangesComponent;

  constructor() {
   this.reset();
  }

  reset() {
    // new Hero object every time; triggers onChanges
    this.hero = new Hero('Windstorm');
    // setting power only triggers onChanges if this value is different
    this.power = 'sing';
    if (this.childView) {
      this.childView.reset();
    }
  }
}

on-changes.component.ts

@Component({
  selector: 'on-changes',
  template: `
  <div class="info">
    <p>{{hero.name}} can {{power}}</p>

    <h3>Change Log</h3>
    <div *ngFor="let chg of changeLog" class="log">{{chg}}</div>
  </div>
  `
})
export class OnChangesComponent implements OnChanges {
  @Input() hero!: Hero;
  @Input() power = '';

  changeLog: string[] = [];

  ngOnChanges(changes: SimpleChanges) {
    for (const propName in changes) {
      console.log(propName)
      const chng = changes[propName];
      const cur  = JSON.stringify(chng.currentValue);
      const prev = JSON.stringify(chng.previousValue);
      this.changeLog.push(`${propName}: currentValue = ${cur}, previousValue = ${prev}`);
    }
  }

  reset() { this.changeLog = []; }
}

After adding console.log to ngOnChanges I noticed that it’s running when I update Power input , however, it’s not running when I update Hero.name. I expected ngOnChanges to run in both cases. What did I miss? I’d appreciate your explanation.

>Solution :

It doesn’t trigger because it is still the same hero you’re referencing, only with a different name. Since Angular uses === to check changes it decides the object didn’t change.

A way to fix this is creating a new hero object each time the name changes or implement the ngDoCheck interface to implement your custom change detection.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading