0

I have a parent component that creates an object myObject with an array property myArray. It injects this object into a child component via one-way binding. The child object uses *ngFor to display members of the array, and it has further child components that bind to properties of the objects in the array, and so on.

I am attempting replace myObject with a new object via myObject = new MyObject(), or to empty myArray via myObject.myArray.length = 0; or myObject.myArray = [];

My expectation is that the child component would then display nothing until I re-populate the array. Instead, in any of the above cases, the child component continues to display the elements of the array as though I hadn't touchedmyObject or myArray at all.

I've tried a few methods of forcing a refresh that I found elsewhere on StackOverflow to no avail, so please excuse a bit of clutter in the current code.

Parent component (.ts) - This function is called when I press a certain button in the template:

create() {
    this.active = false;
    this.changeDetectorRef.detectChanges();
    this.myObject = null;
    this.myObject = new MyObject();
    this.myObject.myArray = null;
    this.myObject.myArray = [];
    this.myObject.myArray.length = 0;
    this.active = true;
    this.changeDetectorRef.detectChanges();
}

I've tried to see what happens when I do console.log(myObject) immediately after every line of this create() function. In every single case, what I get in the console looks like this:

MyObject {myArray: Array(0)}

It looks right, but when I expand that object in the console, it shows that myArray actually still has all of the items it had previously.

Parent component template (.html)

<my-child *ngIf="active"
    [myObject]="myObject"
></my-child>

Child component (.ts)

@Input() myObject:MyObject = new MyObject();

Child component template (.html)

<ng-container *ngFor="let item of myObject.myArray">
    <another-child-component
        [item]="item"
        etc.
    ></another-child-component>
</ng-container>

I am logging every time the child component's ngOnInit() function is called, so I know that the active flag and the changeDetectorRef are forcing it to reinitialize as desired. I also can see the MyObject() constructor getting called enough times to know that the child component is re-instantiating its myObject every time it gets reinitialized.

Yet no matter what I do or where I call it from, I can see that the whole system is still displaying the old myObject and if I call console.log(this.myObject), no matter where or when, it will always output the old copy.

I don't understand this. Why are my child components hanging onto their old objects even after re-initialization?

  • Check: https://stackoverflow.com/questions/38571812/how-to-detect-when-an-input-value-changes-in-angular – W.S. Jul 16 '22 at 23:19

1 Answers1

1

If you want the child to update its @Input() value when parent changes it, then you need to use OnChanges life cycle hook on the child component.

export class ChildComponent implements OnChanges {
  ngOnChanges(changes: SimpleChanges): void {
    console.log(changes);
    // Assign your variables once again here
  }
}
Mohamed Karkotly
  • 1,364
  • 3
  • 13
  • 26