`[class]` bindings have different behavior with input/template bindings when ExpressionChangedAfterChecked
See original GitHub issue🐞 bug report
Affected Package
@angular/core
render3 with ivy
@angular/core/src/render3/instructions/styling.ts
Is this a regression?
no
Description
Set an object to the same value(creating another new instance) in the ngAfterViewInit
, the [class]
binding would report ExpressionChangedAfterChecked error.
it should have the same behavior with the template/input binding, which should not report ExpressionChangedAfterChecked error
🔬 Minimal Reproduction
ivy can not work in stackblitz now, here is the repo
https://github.com/vthinkxie/ng-class-binding-bug/blob/master/src/app/app.component.ts
import { AfterViewInit, Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
{{ classMap | json }}
<!-- this won't report error -->
<app-test [classMap]="classMap"></app-test>
`,
host: {
// this would report error
'[class]': 'classMap'
}
})
export class AppComponent implements AfterViewInit {
classMap = {
test: true
};
ngAfterViewInit(): void {
this.classMap = {
test: true
};
}
}
🔥 Exception or Error
ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: '[object Object]'. Current value: '[object Object]'.
🌍 Your Environment
Angular Version:
@angular-devkit/architect 0.900.0-rc.10
@angular-devkit/build-angular 0.900.0-rc.10
@angular-devkit/build-optimizer 0.900.0-rc.10
@angular-devkit/build-webpack 0.900.0-rc.10
@angular-devkit/core 9.0.0-rc.10
@angular-devkit/schematics 9.0.0-rc.10
@ngtools/webpack 9.0.0-rc.10
@schematics/angular 9.0.0-rc.10
@schematics/update 0.900.0-rc.10
rxjs 6.5.4
typescript 3.7.5
webpack 4.41.2
Anything else relevant?
Issue Analytics
- State:
- Created 4 years ago
- Comments:13 (12 by maintainers)
Top Results From Across the Web
html table - Angular ngFor class binding ... - Stack Overflow
First of all it is this error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'false' ...
Read more >Template type checking - Angular
Angular maintains the behavior of the fullTemplateTypeCheck flag, ... Verifies that component/directive bindings are assignable to their @Input() s ...
Read more >Component - Angular
Maps class properties to host element bindings for properties, attributes, ... NgModule in order for it to be available to another component or...
Read more >do Bindings in Classes - F# | Microsoft Learn
Learn how to use an F# 'do' binding in a class definition, ... to guarantee that members behave as expected, do bindings are...
Read more >Structured binding declaration (since C++17)
an expression that does not have the comma operator at the top level (grammatically, an assignment-expression), and has either array or non-union class...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
@vthinkxie yeh, as hinted above, I think that the following is going on:
ExpressionChangedAfterItHasBeenCheckedError
is not super consistent and sometimes this error is not thrown where (IMO) it should - this is what I’ve meant by “things working by chance”.Again, thnx for the use-cases, let me dig into it a bit more and comment back on the issue with the findings.
I got your point Pawel Kozlowski, Thanks for your quick response!
renderer.
addClass
removeClass
setStyle
removeStyle
works but there are too many boilerplate code when we want to set the class/style dynamicly.it would be better if
renderer
could provide equivalent functionality to template className and style binding (like[class]
and[style]
).