Angular change detection error: ExpressionChangedAfterItHasBeenCheckedError

expressionchangedafterithasbeencheckederror angular 7
angular expressionchangedafterithasbeencheckederror: expression has changed after it was checked
expressionchangedafterithasbeencheckederror angular 9
expressionchangedafterithasbeencheckederror ngmodel
ngclass expressionchangedafterithasbeencheckederror
expressionchangedafterithasbeencheckederror ngfor
angular ngoninit expressionchangedafterithasbeencheckederror
angular university expressionchangedafterithasbeencheckederror

I am getting this error when input binding value is changed inside the component from null/undefiend to some value. Below is the URL for sample code.

https://stackblitz.com/edit/angular-h61csi

Why do I get this error? Someone please explain me how to resolve this without setTimeout.


You can put setting this.selectedItem in a setTimeout.

setTimeout(() => {
  if(!this.selectedItem) {
    this.selectedItem = this.items[1];
    this.cdr.markForCheck();
  }
});

To know why and when this error occurs you can read about ExpressionChangedAfterItHasBeenCheckedError here - https://blog.angularindepth.com/everything-you-need-to-know-about-the-expressionchangedafterithasbeencheckederror-error-e3fd9ce7dbb4

`ExpressionChangedAfterItHasBeenCheckedError` error, During change detection Angular performs checks for each component which consists of the following operations performed in the specified order  ExpressionChangedAfterItHasBeenCheckedError is thrown when an expression in your HTML has changed after Angular has checked it (it is a very expressive error).


Totally agree with @vatz response with small correction. We don't need 'this.cdr.markForCheck()', its required only when we have onpush change detection used in the component.

setTimeout(() => {
  if(!this.selectedItem) {
    this.selectedItem = this.items[1];
  }
});

ExpressionChangedAfterItHasBeenCheckedError Explained, If Angular runs change detection until the model stabilizes, it might run triggered again, the flag's value has changed and the error is thrown. Relevant change detection operations # A running Angular application is a tree of components. During change detection Angular performs checks for each component which consists of the following operations performed in the specified order: update bound properties for all child components/directives


I think the best way to resolve your issue is to redesign your components a bit. Your child component shouldn't pass values back to the parent component, especially if the parent component already knows what the values are, i.e the AppComponent in your case, knows exactly what the values of the selectedItem and the items array are, so you can put the logic from the AfterViewInit hook of the child component in the parent component. Simply change the selectedItem field to:

private _selectedItem: Object;

public get selectedItem() {
    return this._selectedItem ? this._selectedItem : this.items[1];
}

And then remove the code from the AfterViewInit hook in the child component and everything should work without errors. Otherwise, you will have to use setTimeout.

Angular Debugging "Expression has changed": Explanation (and Fix), Error Message Example. The code above will throw the following change detection error: CourseComponent.html:13 ERROR Error:  Everything you need to know about change detection in Angular Think about why you need to change the property in the ngAfterViewInit lifecycle hook. Any other lifecycle that is triggered before ngAfterViewInit/Checked will work, for example ngOnInit or ngDoCheck or ngAfterContentChecked .


ExpressionChangedAfterItHasBeenCheckedError with Interceptor , Bug Report Affected Package "@angular/core": "8.2.5" of the values changed between the start and end of a particular change detection run. When we trigger change detection for the parent A component, Angular will run change detection for all child components as well and so there’s a possibility of parent property update anew. Why do we need verification loop. Angular enforces so-called unidirectional data flow from top to bottom.


Issue #6005 · angular/angular, I think you should internally force new change detection round so that it is bug(​perf): angular2/upgrade keeps running $rootScope.apply() if watchers ExpressionChangedAfterItHasBeenCheckedError when using *ngFor  The ExpressionChangedAfterItHasBeenCheckedError is a really common error when developing Angular applications. This error is mostly hard to find. In the following lines, I will describe a possible way to find the affected variable(s)/parameters from the application to perform a deeper analysis in your code.


Change Detection: When using setTimeout() is not your best option , ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression To make Angular's change detection more efficient it expects  ExpressionChangedAfterItHasBeenCheckedError is thrown when you try to modify a component's state after the change detection algorithm ended. Your issue is that ngAfterViewInit happens, as the name suggests after the change detection algorithm ended. At that point, Angular expects nothing else to change in the component's state until the next tick.