My angular application stuck with a issue, i used input as array and pushed a value to the array when the click event arise. But the ngOnChanges not firing when the array push is done. Is there a way to fire ngOnChange
My Code is ts file is
@Component({
selector: 'adv-search',
templateUrl: './app/modules/result.html'
})
export class InputComponent {
@Input() metas:any=[];
ngOnChanges() {
console.log(this.metas);
}
}
My Selector Tag
<adv-search [metas] = "metaIds"></adv-search>
Click Event Code
insertIds(id:any) {
metaIds.push(id);
}
ngOnChanges gets called before ngOnInit and whenever a component's bound input is changed FROM THE PARENT COMPONENT. Remember that ngOnChanges is specific to bound inputs on the component. This means if you don't have any @Input properties on a child, ngOnChanges will never get called.
The ngOnChnages is a life cycle hook, which angular fires when it detects changes to data-bound input property. This method receives a SimpeChanges object, which contains the current and previous property values. The child Component decorates the property using the @Input decorator.
ngOnChanges() ( OnChanges ) is called when a value bound to an input has changed so you can run custom code when an input has changed. ngDoCheck() ( DoCheck ) is called when change detection runs so you can implement your custom change detection action.
With this update, ngOnChanges immediately fires. It also fires upon initialization of input data. The hook receives one optional parameter of type SimpleChanges . This value contains information on the changed input-bound properties.
Angular change detection only checks object identity, not object content. Inserts or removals are therefore not detected.
What you can do is to copy the array after each update
insertIds(id:any) {
this.metaIds.push(id);
this.metaIds = this.metaIds.slice();
}
or use IterableDiffer
to check for changes inside InputComponent
in ngDoCheck
like NgFor
does.
If you reassign your metaIds array, the ngOnChanges lifecycle event will be fired. You can deconstruct your array into a new array.
insertIds(id:any){
this.metaIds = [...this.metaIds, id];
}
@GünterZöchbauer 's answer is completely correct. However, I would like to add a alternative/supplement to copying the whole array. Using the same example from the question.
<adv-search [metas] = "metaIds"></adv-search>
altered to
<adv-search [metas] = "{trackBy: metaIds.length, metaIds: metaIds}"></adv-search>
Where length here is the equivalent of the *ngFor trackBy function for the component. With this the ngOnChanges occurs with content length changes.
If used in combination with the *ngFor trackBy method there should be some performance benefits as the whole array's bound templates are not recalculated (no screen/content flickering).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With