import {Injectable, NgZone, TemplateRef} from '@angular/core'; import {Observable, Subject} from 'rxjs'; import {MatDialog, MatDialogConfig, MatDialogRef} from '@angular/material/dialog'; import {ComponentType} from '@angular/cdk/portal'; type Dialog = {subject: Subject, dialog_service_identifier: string}; @Injectable({ providedIn: 'root' }) export class DialogService { private dialogs: Record>> = {}; constructor(public materialDialog: MatDialog, private zone: NgZone) {} public show(dialogType: ComponentType | TemplateRef, configuration?: MatDialogConfig): Observable { // Now using NgZone to avoid weird bug where ngOnInit would only be called after dialog was closed, // thus rendering an empty unusable dialog return this.zone.run(() => { const dialog = this.materialDialog.open(dialogType, Object.assign({width: '400'}, configuration || {} ) ); dialog.componentInstance.dialog_service_identifier = `dialog_${new Date().getTime()}`; this.dialogs[(dialog.componentInstance as any).dialog_service_identifier] = dialog; return dialog.afterClosed(); }); } public close(dialog: any, value?: T): void { if (dialog) { this.getDialog(dialog).close(value); } } private getDialog(dialog: any): MatDialogRef { const result = this.dialogs[dialog.dialog_service_identifier]; if (result) { return result; } throw new Error('Could not close dialog - did you try to close it without opening it?'); } public getDialogs(): Record>> { return this.dialogs; } }