-
Notifications
You must be signed in to change notification settings - Fork 27k
Description
I'm submitting a...
[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
Current behavior
The current warning message ExpressionChangedAfterItHasBeenCheckedError is telling us what are the values before and after the change detection, but there aren't enough information to help to debug.
We are never sure what object or property is referring to. Also, the lines are not always reliable.
In some cases, we use an array of objects and messages like so are provided:
ERROR Error: ExpressionChangedAfterItHasBeenCheckedError:
Expression has changed after it was checked.
Previous value: 'undefined'. Current value: '[object Object],[object Object]'.
at viewDebugError (errors.ts:30)
at expressionChangedAfterItHasBeenCheckedError (errors.ts:29)
at checkBindingNoChanges (util.ts:145)
at checkNoChangesNodeInline (view.ts:477)
at checkNoChangesNode (view.ts:568)
at debugCheckNoChangesNode (services.ts:557)
at debugCheckDirectivesFn (services.ts:466)
at Object.View_App_0._co [as updateDirectives] (App.html:7)
at Object.debugUpdateDirectives [as updateDirectives] (services.ts:443)
at checkNoChangesView (view.ts:378)
I can see the file name is (App.html:7), so I presume is something in my template, but it's not clear what it is. Also, note that my bug should be on line 2 (<div *ngIf="testObject">), and not on line 7 as mentioned by angular.
Expected behavior
Perhaps, it would be nice adding to the warning message the property/object that has changed its value.
I would expect the warning message being something like so, instead:
ERROR Error: ExpressionChangedAfterItHasBeenCheckedError:
Expression has changed after it was checked.
Previous testObject value: 'undefined'. Current testObject value: '[{a: 1, b: 2}, {a: 3, b: 4}]'.
PS: note the
testObjectkey from my App class, also the values from object as string.
In that case, it would be easier to debug that the object is testObject;
Minimal reproduction of the problem with instructions
This plunker can give an example of the context provided by angular. http://plnkr.co/edit/mX6REf9oidrVeURCvTZG?p=preview
This plunker is a fork from @adrienboulle from #14748 (comment)
@Component({
selector: 'my-app',
template: `
<div>
<div *ngIf="testObject">
Object exists
</div>
<div class="image-container"
[ngStyle]="{
'height': getHeightPx()
}">
<img alt="image" style="height: 100%" [src]="getUrl()"/>
</div>
</div>
`,
})
export class App implements AfterViewInit {
img: Image;
isLoaded: boolean = false;
testObject: any;
constructor(private elementRef: ElementRef) {}
public ngAfterViewInit(): void {
this.img = this.elementRef.nativeElement.querySelector('img');
this.isLoaded = true
this.testObject = [{a: 1, b: 2}, {a: 3, b: 4}];
}
public getUrl(): string {
return 'https://angular.io/resources/images/logos/angular2/angular.png';
}
public getHeightPx(): string {
if (!this.isLoaded)
return '0px';
return '100px';
}
}If you comment line 33: // this.testObject = [{a: 1, b: 2}, {a: 3, b: 4}];, you will end up with another bug with the same issue, but now, referring to the getHeightPx() method which was pointed by @adrienboulle on the issue #14748.
App.html:9 ERROR Error: ExpressionChangedAfterItHasBeenCheckedError:
Expression has changed after it was checked. Previous value: '0px'. Current value: '100px'.
In that case, it's much easier to debug. The line 9 is correct.
Also, because of its values ('0px' and '100px'), it is easier to find the property. However, the message error could have the missing getHeightPx() method which would make the debugging easier.
What is the motivation / use case for changing the behavior?
Make it easier to debug this popular error #18129 #17887 #17572 #15464 #14748 and many other issues.
Environment
Angular version: 4.3.6