[Fixed] The Parent Variable is not updating in the child Component in Angular

Issue

I have a variable in the parent component like this:

ParentComponent

export class ParentComponent {
    
  variable = {};
  varExample = false;
  @ViewChild('child') child: ChildComponent;
  
  someFunction () {
    this.variable['id'] = {};
    for (let i = 0; i < 10; i++) {
      this.variable['id'][i] = i*2; 
    }
    this.varExample = true;
  }

  otherFunction () { // called when i click a button
    this.someFunction ();
    
    console.log(this.child.variable); // {}
    console.log(this.child.varExample); // true
    this.child.initVars();
  }
}

Parent HTML

<app-child #child [variable]="variable" [varExample]="varExample"></app-child>

ChildComponent

export class ChildComponent {
  @Input() variable: any;
  @Input() varExample: boolean;

  initVars() {
    console.log(this.variable); // {}
    console.log(this.varExample); // true
  }
}

This is just an example of my implementation and yes I have all imports.

In those console.log(this.variable) I got an empty object ( {} ), but varExample still works fine.
Why is child’s variable always empty, Angular doesn’t detect changes in this type of Objects ( {} ) ?

Can someone help me?

Solution

  1. The answer is already in the question. For varExample you reassign it’s value this.varExample = .... But for this.variable only it’s contents are changed. When the underlying reference doesn’t change, Angular won’t detect it’s changes.
    You could either use the solution from @user2846469 or use spread syntax to adjust the values and reference inline.

Parent

someFunction() {
  this.variable["id"] = {};
  for (let i = 0; i < 10; i++) {
    this.variable = {
      ...this.variable,
      id: {
        ...this.variable["id"],
        [i]: i * 2
      }
    };
  }
  this.varExample = true;
}
  1. Using @ViewChild to trigger another component’s function is inelegant. Instead you could use OnChanges hook in the child component. It will be triggered whenever a change is detected in any of the @Input variables.

Child

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

export class ChildComponent implements OnChanges {
  @Input() variable: any;
  @Input() varExample: boolean;

  ngOnChanges(changes: SimpleChanges) {
    if (changes.variable && changes.variable.currentValue) {
      console.log(changes.variable.currentValue);
    }
  }
}

Working example: Stackblitz

Leave a Reply

(*) Required, Your email will not be published