6

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
  • try changing @Input() variable: any; to @Input() variable: {}; Commented Mar 15, 2021 at 10:39
  • doens't work, i already tried that. Commented Mar 15, 2021 at 10:40

2 Answers 2

11
  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

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the help and suggestion for a change detection
1

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.