Explaining the Angular Error: 'Expression Changed After It Has Been Checked'
One of my colleagues encountered an error message while developing an Angular frontend application. The error message read:
ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'null', Current value: 'true'.
This error occurred while he was developing a back button feature that navigates from the second page to the first. The first page had already been rendered once and needed to be re-rendered with different initial values.
The root cause of this error lies in Angular’s change detection mechanism. After each operation, Angular stores the values it used for that operation in the component view’s oldValues
property. Once all components have been checked, Angular initiates the next digest cycle. However, instead of performing operations, it compares the current values with those stored from the previous cycle.
It’s worth noting that this additional level of checking only occurs in development mode. Angular enforces a unidirectional data flow from the top of the component tree to the bottom. No child component is allowed to update the properties of a parent component once the parent’s changes have been processed.
To resolve the above issues, possible solutions include using asynchronous updates, such as setTimeout
, or manually triggering change detection at the ngAfterViewInit()
lifecycle hook with _changeDetectorRef.detectChanges()
. The ChangeDetectorRef
class provides the following five methods:
abstract class ChangeDetectorRef {
abstract markForCheck(): void;
abstract detach(): void;
abstract detectChanges(): void;
abstract checkNoChanges(): void;
abstract reattach(): void;
}
By utilizing these methods, you can manually run change detection and update the child view. My colleague was pleased to find that the error was resolved following this explanation.