Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mat Dialog Error in Angular Component ExpressionChangedAfterItHasBeenCheckedError

I am using Angular Material with Angular 6 where it is like on ngOnInit I have to display content if condition is correct.

I have Dialog Module using which I am displaying Dialog

  `if (!this.checkforRestriction()) {
  this.loadContent(this.ReferenceID);
} else {
  this.dialogService.okmessage('', dialogMessage);
}` 

ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'id: undefined'. Current value: 'id: mat-dialog-0'. It seems like the view has been created after its parent and its children have been dirty checked. Has it been created in a change detection hook ? at viewDebugError (core.js:8445)

I am getting this error. Kindly suggest what is wrong ?

like image 551
poojagupta Avatar asked Aug 01 '18 09:08

poojagupta


People also ask

What is Mat dialog in angular?

The MatDialogRef provides a handle on the opened dialog. It can be used to close the dialog and to receive notifications when the dialog has been closed. Any notification Observables will complete when the dialog closes. dialogRef.


Video Answer


2 Answers

It's hard to tell what's causing the problem without knowing a lot of details about all the invoked functions. However, ExpressionChangedAfterItHasBeenCheckedError can most likely be fixed by doing the following:

  • try moving the code into ngAfterViewInit lifecycle hook,
  • try wrapping the code inside the setTimeout.

Finally, read Everything you need to know about the ExpressionChangedAfterItHasBeenCheckedError error. It should give you a better idea about the error you are facing.

like image 84
Tomasz Kula Avatar answered Sep 22 '22 14:09

Tomasz Kula


I experienced this same underlying issue with the following error:

ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'aria-labelledby: null'. Current value: 'aria-labelledby: mat-dialog-title-0'."

My dialog contains this directive for the title:

<h1 mat-dialog-title>{{ model.title }}</h1>

Angular tries to apply the aria-labelledby attribute to the parent container of my dialog's component (mat-dialog-container). It isn't able to do so if you're opening the dialog in the callback from an http load.

In my case I was opening the dialog as part of an RxJS 'pipe' and adding delay(0) after the http get was effectively doing a 'setTimeout'.

eg.

const result = this.http.get(...).pipe(
                                       delay(0), 
                                       switchMap(response => {

   if (response.hasOverdueLibraryBook) {

       return this.dialogManager.openOverdueLibraryBookDialog();  // this is a mat-dialog
   }
   else 
   {
      return of(false);
   }

});
like image 36
Simon_Weaver Avatar answered Sep 22 '22 14:09

Simon_Weaver