Angular material dialog - pass types into dialog component
TL;DR:
You can use the following code to specify the type that your dialog's data will use:
import { MatDialog } from '@angular/material/dialog';export class MyComponent { constructor(private dialog: MatDialog) { } openDialog() { this.dialog.open<MyDialogComponent, MyType>(MyDialogComponent, { data: { // Your data goes here } }; }}
In your dialog component:
import { MAT_DIALOG_DATA } from '@angular/material/dialog';export class MyDialogComponent { constructor(@Inject(MAT_DIALOG_DATA) public data: MyType) { }}
The open
method of the MatDialog
class actually allows three types to be specified (in order of sequence):
T
: The component class (optional - although there's no default value, you don't have to specify it if you're just calling the method without any other types)D
: The type to be used for the data to be added to the dialog (optional - defaults toany
)R
: The type to be used for the result of the dialog (optional - defaults toany
)
The method is defined as below:
/** * Opens a modal dialog containing the given component. * @param componentOrTemplateRef Type of the component to load into the dialog, * or a TemplateRef to instantiate as the dialog content. * @param config Extra configuration options. * @returns Reference to the newly-opened dialog. */ open<T, D = any, R = any>(componentOrTemplateRef: ComponentType<T> | TemplateRef<T>, config?: MatDialogConfig<D>): MatDialogRef<T, R> { // ... }
The D
type is then passed to MatDialogConfig
, which accepts the same type to be used for the data to be passed in to the dialog.
References:
MatDialog#open
source code - notice how the types are passed around in the code!MatDialogConfig
source code - notice how the class is defined!
I don't think it's possible to have a typed dialog the way you outlined it. But what you can do is something like:
export class MyDialog { private savedForLater: SomeType; constructor( public containingDialog: MatDialogRef<MyDialog>, @Inject(MAT_DIALOG_DATA) public data: SomeType) { this.savedForLater = data; }}
Unfortunately when you launch the dialog the type isn't enforced so you could still do this
const dialogData = {} as SomeTypeconst fakeDialogData = {} as SomeOtherTypethis.dialog.open(MyDialog, { data: dialogData });this.dialog.open(MyDialog, { data: fakeDialogData }); // this compiles