2

When I make a change to a property of an object, Angular's default change detection is not working:

@Component({
    selector: 'parent-comp',
    template: `<child-comp [mutableObject]="mutableObject"></child-comp>`
})
export class ParentComp implements OnInit {

    mutableObject: MutableObject = { someProp: 'hello' };

    onClickedSomething() {
        this.mutableObject.someProp = 'goodbye';
    }
}

@Component({
    selector: 'child-comp',
    template: `<h1>{{ mutableObject.someProp }}</h1>`
})
export class ChildComp implements OnInit, OnChanges {

    @Input() mutableObject: MutableObject;

    ngOnInit() {}

    ngOnChanges(changes: SimpleChanges) {
        console.log('change detected');
    }
}

ngOnInit gets called in child component the first time both parent and child components load, but when onClickedSomething() method changes the property value, the child component doesn't detect the change. I made sure that ChangeDetectionStrategy.OnPush is not being used. What could be going wrong here?

1 Answer 1

3

Nothing is going wrong here. Like you say, the underlying reference to the object isn't changed. So Angular doesn't honour the change in object properties. Try to force it using the spread operator and reassign the variable.

export class ParentComp implements OnInit {
  mutableObject: MutableObject = { someProp: 'hello' };

  onClickedSomething() {
    this.mutableObject = { ...this.mutableObject, someProp: 'goodbye' };
  }
}

Obviously the spread operator in the assignment is redundant here since the object contains only one property. But it'll be required when there are multiple properties and you wish to change only few of them.

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

3 Comments

This was just a quick sample of what I'm doing. In reality, the object that's changing is quite deep, so it would be a shame if I had to do a deep clone of the object every time one if its properties change. I would like to retain all the property values that haven't changed.
Exactly the reason for the spread operator. It'll retain all the values except the ones that are changed explicitly.
I've got a question about this. Let's say that the mutable object holds properties that other components use. How would I know which properties changes specifically for each component? Rather than passing down the whole object, would it be best to just pass the properties that are needed?

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.