'Why ngOnChanges() does not trigger when @Input() update the data Angular 8?
parent.component.html
<parent-comp [data]="mydata"> </parent-comp>
parent.component.ts
this.service.abc$
.takeUntil(this.ngUnsubscribe.asObservable())
.subscribe((data: myType[]) => {
this.mydata= data;
});
child.component.ts
@Input data;
Under Class I have below code
public ngOnChanges() { if (this.data) { console.log(this.data); } }
Now I want whenever I receive latest data in @Input data
from Parent Component to child then my ngOnChanges
function should trigger and print data in console.
But unfortunately ngOnChanges
function does not trigger again. It trigger only once when component initialize
Please let me know if anyone wants more detail on same!
Thanks!
Solution 1:[1]
Given the lack of further information, I'd make an informed guess that @Input data
is either an array or an object.
According to docs, ngOnChanges
is:
A lifecycle hook that is called when any data-bound property of a directive changes.
What it doesn't say however is how the property should be changed. Generally speaking, the hook is only triggered when the reference to the property is changed.
Consider the following eg.
Parent component controller
mydata = [];
updateMyData(value: any) {
this.mydata.push(value);
}
Parent component template
<app-child [data]="mydata"></app-child>
Child component controller
@Input() data: any;
ngOnChanges(changes: SimpleChanges) {
console.log(changes);
}
Now you'd expect the ngOnChanges
will be triggered every time the updateMyData()
function is called in the parent component. But the reference to the variable mydata
is never changed. So the hook won't be triggered. There are multiple ways to force the change detector to trigger the hook.
Method 1:
Bind the @Input
decorator to a setter instead of the variable directly. Discussed in an answer already.
Method 2: Use spread syntax to re-assign the variable in the parent component.
Parent component controller
mydata = [];
updateMyData(value: any) {
this.mydata = [...this.mydata, value];
}
You could use the same methods for objects as well.
Solution 2:[2]
Thank you everyone for your quick and effective solutions.
I got solution and it is not exactly but similar to what you guys suggested.
In the Parent Component:
**Earlier I was assigning this way**
`this.mydata= data;`
**But now I am assigning in below way:**
`this.mydata= cloneDeep(data);`
Note : cloneDeep
is imported from lodash
Solution 3:[3]
It could be the data you are passing down. If it doesn't change then the ngOnChanges won't register any changes. Here's an example, you can see if a property changes multiple times then it will only trigger on the first update, but if you recreate the object it changes every time. (see console logs in stackblitz)
https://stackblitz.com/edit/angular-ivy-qmb35h?file=src%2Fapp%2Fapp.component.html
You can do as I did and recreate the object each time to bypass this, or a more hacky way may be to keep a dummy 'count' variable that you pass down as well, and increment it each time you want the child component to register the change.
Solution 4:[4]
NgOnChanges will only be triggered for an input-bound property change of primitive type. That is because the reference to the data-variable has to be changed in order for the change to be registered, so that you can get it in this life-cycle hook.
So, the possible way you could achieve this is by changing the reference of 'mydata' variable. Like, assigning a new reference to the mydata variable when it is changed, mydata = [...mydata]
if it is an array, or mydata = {...mydata}
if it is an object from the parent component.
Solution 5:[5]
you can use setter and getter methods for @Input in angular. Please refer the below lines for reference:
private _data: any;
@Input()
set data(data) {
this._data = data;
console.log(this._data);
};
From setter method only you can call any other method as well and can run any logic you want from there.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Ambuj Khanna |
Solution 3 | iamaword |
Solution 4 | Gauri Kesava Kumar |
Solution 5 | Minal Shah |