Skip to content

ExpressionChangedAfterItHasBeenCheckedError is not thrown if ChangeDetection.OnPush is used #45612

@skrtheboss

Description

@skrtheboss

Which @angular/* package(s) are the source of the bug?

core

Is this a regression?

No

Description

When changing a template value while the change detection is taking place, the user is warned with an ExpressionChangedAfterItHasBeenCheckedError.
This is not the case for components which use the ChangeDetectionStrategy.OnPush .

By doing some debugging I found the problem:

  1. The async pipe triggers a markForCheck for the component, while change detection is running.
  2. The refreshView clears the dirty state of the component after the view has been checked.
  3. The checkNoChanges is performed, and the refreshComponent function does not perform a refreshView for that component, since it is no longer dirty.

This results in no ExpressionChangedAfterItHasBeenCheckedError because the view is not checked, since its dirty status has been cleared in the change detection process

This can be really hard to debug without the warning. So I found a workaround for now, that is to add || isInCheckNoChangesMode() to the refreshView check so that it becomes if (componentView[FLAGS] & (LViewFlags.CheckAlways | LViewFlags.Dirty) || isInCheckNoChangesMode()) {. This is very ugly and imperformant, but at least it helps detect those errors.

Please provide a link to a minimal reproduction of the bug

https://stackblitz.com/edit/angular-ivy-ked7hw?file=src/app/app.component.ts

Please provide the exception or error you saw

No response

Please provide the environment you discovered this bug in (run ng version)

Angular CLI: 13.3.2
Node: 16.14.2
Package Manager: yarn 1.22.18
OS: linux x64

Angular: 13.3.2
... animations, cdk, cdk-experimental, cli, common, compiler
... compiler-cli, core, forms, material, material-moment-adapter
... platform-browser, platform-browser-dynamic, router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1303.2
@angular-devkit/build-angular   13.3.2
@angular-devkit/core            13.3.2
@angular-devkit/schematics      13.3.2
@schematics/angular             13.3.2
ng-packagr                      13.3.0
rxjs                            7.5.5
typescript                      4.6.3
webpack                         5.72.0

Anything else?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3An issue that is relevant to core functions, but does not impede progress. Important, but not urgentarea: coreIssues related to the framework runtimebreaking changescore: change detection

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions