circuit

How to detect when an input() value changes in Angular

Detect when input value changes in Angular




Photo by Elena Koycheva on Unsplash

We mostly deal with the parent-child component relations in the angular applications but sometimes it happens that we parent component makes some changes but the child component won’t notify or change values directly. How we can notify children or update input values directly?

1. Using the ngOnChanges() lifecycle method

**ngOnChanges **method gets called when any input values changes happen in the Component.This method has a **SimpleChanges **object from which we can compare current and previous values.

@Input() testId: string;

    ngOnChanges(changes: SimpleChanges) {

        this.doSomething(changes.testId.currentValue);
        //

    }

2. Using Input Setter and Getter Property

We can create getter and setter methods, the benefit from this is whenever changes happen setter will set the value and we get the updated value.

private _testId: string;

[@Input](http://twitter.com/Input)() set testId(value: string) {

this._testId= value;
    this.changeHappened(this._testId);

}

get testId(): string {

return this._testId;

}

3. We can use an Async pipe.

[@Component](http://twitter.com/Component)({
    selector: 'child-component',
    template: `<p>{{ data }}</p>`,
})
export class SubComponent implements OnInit {
    [@Input](http://twitter.com/Input)() data: string;

ngOnInit() {
        console.log('received data', this.data);
    }
}

[@Component](http://twitter.com/Component)({
    selector: 'Parent-app',
    template: `
    <h1>Hello {{name}}</h1>
    <sub-component [data]="data$ | async"></sub-component>
  `
})
export class ParentCOmponent {
    data$ = Observable.of('Values').delay(1000);
}

Async Pipe does the following tasks.

  • The async pipe subscribe to Observable and returns the latest emitted value.

  • This pipe will only check for changes when we get the new changes

  • Which will help to avoid any memory leaks.

Which approach should you use?

If you need to check the previous values and current values and do some checks for multiple inputs together it is better to go with the ngOnChanges() as we need to handle multiple things in setter and getter.

The most efficient approach is to go with Async Pipe as it helps to unsubscribe itself which eventfully helps not to write or care about unsubscribe.

Angular change detection may not fire under certain circumstances

Normally, change detection for both setter and ngOnChanges will fire whenever the parent component changes the data it passes to the child, provided that the data is a JS primitive datatype(string, number, Boolean). However, in the following scenarios, it will not fire and we need to take care.

  1. If we are using a nested object or array it might happen that change detection will not notify by itself for that we might need to create a new array or object like this data= {...data};

  2. If you are changing data externally, then angular will not know of the changes. we need to use ChangeDetectorRef or NgZone in our component for making angular aware of external changes and thereby triggering change detection.

References:

How to detect when an @Input() value changes in Angular?




Continue Learning