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
- The answer is already in the question. For
varExample
you reassign it’s valuethis.varExample = ...
. But forthis.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;
}
- Using
@ViewChild
to trigger another component’s function is inelegant. Instead you could useOnChanges
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