There are 2 child-components (bar/edit) under app-component, edit component will emit an @output number
from ngOnChanges
function to the app component . Which the app component will stored it like below.
app.component.ts
editCount:number=0;
editCountReceiver(data:number){
this.editCount=data;
console.log("app component receieved = "+this.editCount);
}
app.component.html
<app-edit (send_edit_count)="editCountReceiver($event)"></app-edit>
The bar component will then get the number from the app component by using @input
like below .
app.component.html
<app-search-bar [total_edit]="editCount"">
bar.component.typescript
@Input() total_edit: number ;
And then the error appeared.
"ERROR Error: NG0100: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: '0'. Current value: '1'.. "
One line of code is included in the error message, as shown below.
<app-search-bar [total_edit]="editCount"">
I was trying to fix this issue for couple of hours already and I have found out it has to do with the hook thing. So I decided to console.log
almost all hooks for further investigation. The result is quite long so I just capture few lines that I think might be helpful.
Supposedly, since the value is bind with @input
. I expect the ngOnChanges
is called right after app component receive number and update bar component @input
number accordingly.
But no, an error message is appeared before the ngOnChanges
called. I presume it's because the @input
data is updated slower than the afterViewChecked
hook. So please, how can I fix this issue and make sure @input update is detected and applies before the afterViewChecked
hook ?
As you describe, if you need to be notified, it's probably with a Subject that you must subscribe. Since I don't have all the code in your question, it's hard to give you a good answer.
In that case, one component can emit the value with the Subject
by calling next
and the component that need to be notified can Subcribe
to the same Subject
.
After some research, you can use a setter on the Input
, but in this case, you will run after some problems if the value is passed by reference. (ex. An array, or an object).
In that case, something like this can work:
private editCountField: number;
get countField(): number{
return this.editCountField;
}
@Input() set countField(newCountField: number) {
this.editCountField = newCountField;
this.doSomething();
}