The Parent Variable is not updating in the child Component in Angular

Viewed 5522

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?

2 Answers
  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

Yes, I had this issue also. Try it like this:

    someFunction() {
    const tmp = {};
    tmp['id'] = {};
    for (let i = 0; i < 10; i++) {
        tmp['id'][i] = i * 2;
    }
    this.variable = tmp;
    this.varExample = true;
}

i.e. use a temporary object and then assign the object to your variable. I think the issue is with Angular's change detection. If you don't assign it, it doesn't get detected in this case.

Related