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?

1

1 Answer 1

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
  }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.