1

I have one <input> field and one component which have a common model binded. I'm using ngOnChanges() in the component to check the value of that input, and also I'm changing the model binded to that input somewhere in this component.

Let say we binded date variable to the <input> and the component. The error occurs in that situation:

input field changed (also date changed) 
--> ngOnChanges 
--> new value of date doesn't fit requirements 
--> change the date to something else
--> <input> emits the new date
--> ngOnChanges() triggered again
--> ExpressionChangedAfterItHasBeenCheckedError

Here are parts of my code:

app.component.html:

...
<input [(ngModel)]="date">
<app-date-picker [date]="date" (dateUpdated)="setDate($event)"></app-date-picker>
...

app.component.ts:

setDate(newDate: Date): void {
  this.date = newDate.toISOString().split('T')[0];
}

date-picker.component.ts:

  ngOnChanges(changes: SimpleChanges): void {
    if (changes.date) ... // Do some checks
    if (invalidDate) {
       ...
       this.select(newDay);
    }
  }

  select(d: number): void {
    this.selectedYear = this.year;
    this.selectedMonth = this.month;
    this.selectedDay = this.day = d;
    this.dateUpdated.emit(new Date(this.year, this.month, this.day + 1));
  }
Bünyamin Sarıgül
  • 3,031
  • 4
  • 30
  • 55
  • [Everything you need to know about the `ExpressionChangedAfterItHasBeenCheckedError` error](https://medium.com/@maximus.koretskyi/everything-you-need-to-know-about-the-expressionchangedafterithasbeencheckederror-error-e3fd9ce7dbb4) explains this behavior in great details – Max Koretskyi Jul 02 '17 at 05:25

1 Answers1

0

I solved it by changing the date with a timeout:

ngOnChanges(changes: SimpleChanges): void {
  if (changes.date) ... // Do some checks
  if (invalidDate) {
     ...
     setTimeout(() => { select(newDay); }, 50);
  }
}
Bünyamin Sarıgül
  • 3,031
  • 4
  • 30
  • 55