I have read several answers, and I have tried many but I can't seem to get this to work. In my angular 6 app, I try to open a MatDialog but I receive this error:
ERROR Error:
ExpressionChangedAfterItHasBeenCheckedError:
Expression has changed after it was checked. Previous value: '@slideDialog: enter'. Current value: '@slideDialog: exit'.
When I debug the app and click the checkout button, the MatDialog opens and then after stepping through a few more lines it closes. When running the app without breakpoints, you never see the dialog open at all.
Here is the template file:
<div>
<button id="cancelButton" mat-raised-button (click)="clearCart()">Cancel</button>
<button id="checkoutButton" mat-raised-button color="primary" (click)="openCheckoutDialog(dataSource)" [disabled]="isTableEmpty()">Checkout</button>
</div>
When I click the button with the id "checkoutButton" it calls openCheckoutDialog()
Here is my class where openCheckoutDialog is called:
import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
@Component({
selector: 'app-shopping-cart',
templateUrl: './shopping-cart.component.html',
styleUrls: ['./shopping-cart.component.css']
})
export class ShoppingCartComponent implements OnInit {
dataSource: MatTableDataSource<Item>;
itemList: Item[] = [];
constructor(public dialog: MatDialog, private cdr: ChangeDetectorRef) { }
openCheckoutDialog(): void {
const dialogRef = this.dialog.open(ReviewItemListComponent, {
width: '250px',
data: this.itemList
});
// this.cdr.detectChanges();
dialogRef.afterClosed().subscribe(result => {
console.log(`Dialog result: ${result}`);
});
// this.cdr.detectChanges();
}
}
I have tried the this.cdr.detectChanges()
in those 2 places above, but I would still receive the error.
Here is my ReviewItemListComponent template (dialog when the checkout button is clicked):
<div>
<h1 mat-dialog-title>
Are you sure?
</h1>
<mat-dialog-actions>
<button tabindex="-1" mat-raised-button [mat-dialog-close]="true">Cancel</button>
<button tabindex="-1" mat-raised-button color="primary" (click)="confirm()">Confirm</button>
</mat-dialog-actions>
</div>
And here is the ReviewItemListComponent class:
import { Component, OnInit, Inject } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
import { Item } from '../item';
@Component({
selector: 'app-review-item-list',
templateUrl: './review-item-list.component.html',
styleUrls: ['./review-item-list.component.css']
})
export class ReviewItemListComponent implements OnInit {
constructor(public dialogRef: MatDialogRef<ReviewItemListComponent>,
@Inject(MAT_DIALOG_DATA) public data: Item[]) { }
ngOnInit() {
this.dialogRef.close();
}
confirm(): void {
this.dialogRef.close();
}
}
I'm not making any changes to data, which is what most of the questions & answers involve, so how do I resolve this problem regarding opening a MatDialog?
Edit:
Turns out I had pasted this.dialogRef.close()
into the wrong method. In this case I put it inside of ngOnInit()
when I was creating my review-item-list-component.ts file. So once I open it I close it. This still doesn't explain the error. What is so wrong about closing the recently opened dialog inside of ngOnInit()
?
setTimeout
– DistillatengOnInit
. The problem is that the view (dialog) is being modified during the change detection cycle.(which runs twice in dev mode - in prod you would not have this error) If you movedialog.close()
intongAfterViewInit
I believe it should stop that error from being thrown. – DistillateExpressionChangedAfterItHasBeenCheckedError
can be worked-around addingchangeDetectionRef.detectChanges()
on the parent. – Biyearly