How to manage Angular2 "expression has changed after it was checked" exception when a component property depends on current datetime
Run change detection explicitly after the change:
import { ChangeDetectorRef } from '@angular/core';constructor(private cdRef:ChangeDetectorRef) {}ngAfterViewChecked(){ console.log( "! changement de la date du composant !" ); this.dateNow = new Date(); this.cdRef.detectChanges();}
TL;DR
ngAfterViewInit() { setTimeout(() => { this.dateNow = new Date(); });}
Although this is a workaround, sometimes it's really hard to solve this issue in any nicer way, so don't blame yourself if you are using this approach. That's okay.
Examples: The initial issue [link], Solved with setTimeout()
[link]
How to avoid
In general this error usually happens after you add somewhere (even in parent/child components) ngAfterViewInit
. So first question is to ask yourself - can I live without ngAfterViewInit
? Perhaps you move the code somewhere ( ngAfterViewChecked
might be an alternative).
Example: [link]
Also
Also async stuff in ngAfterViewInit
that affects DOM might cause this. Also can be solved via setTimeout
or by adding the delay(0)
operator in the pipe:
ngAfterViewInit() { this.foo$ .pipe(delay(0)) //"delay" here is an alternative to setTimeout() .subscribe();}
Example: [link]
Nice Reading
Good article about how to debug this and why it happens: link
As mentioned by @leocaseiro on github issue.
I found 3 solutions for those who are looking for easy fixes.
1) Moving from
ngAfterViewInit
tongAfterContentInit
2) Moving to
ngAfterViewChecked
combined withChangeDetectorRef
as suggested on #14748 (comment)3) Keep with ngOnInit() but call
ChangeDetectorRef.detectChanges()
after your changes.