Skip to content

MatDialog change detection fail #13640

@ZBAGI

Description

@ZBAGI

Bug, feature request, or proposal:

It's a bug.

What is the expected behavior?

Dialog should close.

What is the current behavior?

After ruining .close method on MatDialogRef on Dialog that was open via service. Application failing to detect change thus Dialog does not disappear until something else triggers application tick ( for example: focusing in and out )

What are the steps to reproduce?

Example: https://stackblitz.com/edit/angular-qdnnb7

  1. Click Continue to "close" dialog.
  2. Dialog will not disappear until something will forces app to detect changes. Even tho it is marked as closed.
  3. To "fully" close dialog (in stackblitz) click in console (right bottom corner). That will force application to detect new changes.

Exact steps to reproduce:

  1. Create component that will be used in dialog.
import { ApplicationRef, Component } from "@angular/core";
import { MatDialogRef } from "@angular/material";

@Component({
  templateUrl: "./exception-dialog.component.html",
  styleUrls: ["./exception-dialog.component.scss"]
})
export class ExceptionDialogComponent {
  public constructor(
    public dialogRef: MatDialogRef<ExceptionDialogComponent>,
  ) { }

  public continue() {
      this.dialogRef.close();
  }
}
<h1 mat-dialog-title>Unexpected problem occurred.</h1>
<div mat-dialog-content>
	Please try again later. If problems persist contact your conferencing administrator.
</div>
<div mat-dialog-actions align="end">
  	<button mat-button (click)="continue()" cdkFocusInitial>Continue</button>
</div>
  1. Create service that will be used to open dialog
import { Injectable } from "@angular/core";
import { MatDialog } from "@angular/material";

import { ExceptionDialogComponent } from "./exception-dialog.component";

@Injectable()
export class NotificationService {
    public constructor(
        public dialog: MatDialog
    ) { }

    public loading: boolean = false;

    public announceUnexpectedError(): void {
        this.dialog.open(ExceptionDialogComponent);
    }
}
  1. Create an custom error handler that uses service to open dialog
import { ErrorHandler, Injectable } from "@angular/core";
import { NotificationService } from "./notification.service";

@Injectable()
export class GlobalErrorHandlerService implements ErrorHandler {
    public constructor(
        private notification: NotificationService
    ) { }

    public handleError(error) {
        this.notification.announceUnexpectedError();
        // throw error;
    }
}
  1. Throw an exception to see dialog
  2. Click Continue to .close dialog. Dialog will technically be closed but it will act as open (that is: will be visible) until something else will force app to detect changes.

What is the use-case or motivation for changing an existing behavior?

I'm not sure what causes it but i guess that it have something to do with opening dialog from service. If that is the case there is a lot of scenarios why someone would like use it this way.
In my example it is notification service that would standardize how and what should pop-ups.

Which versions of Angular, Material, OS, TypeScript, browsers are affected?

Tested on:
@angular/material v6.4.7
Typescript: v2.8.4
Os / browser: irrelevant

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs: clarificationThe issue does not contain enough information for the team to determine if it is a real bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions