I have an existing component ResultGridComponent
that is passed data by @Input()
. I want to use the same component for the MatDialog
.
Hence I added @Inject(MAT_DIALOG_DATA) data
in the constructor of the ResultGridComponent
component.
constructor(private spinner: EdpLoaderService, private dialog: MatDialog, @Optional() @Inject(MAT_DIALOG_DATA) data) {}
But when the component is called as per it's regular usage that is not as a dialog, I get the following error :
ERROR Error: StaticInjectorError(AppModule)[ResultGridComponent -> InjectionToken MatDialogData]: StaticInjectorError(Platform: core)[ResultGridComponent -> InjectionToken MatDialogData]: NullInjectorError: No provider for InjectionToken MatDialogData!
I am pretty sure I have imported all the needed modules. Because I created a separate component for the dialog and passed data to it and it worked fine. But I want to reuse the component. And I am pretty sure this error is coming when I call constructor the of the child component as a regular component and the constructor doesn't get the MatDialogData
passed to it by the caller.
In some cases, I would use @Optional() before the @Inject(MAT_DIALOG_DATA).
constructor(
@Optional() @Inject(MAT_DIALOG_DATA) dialogData: any
) {
if (dialogData) {
// here pass dialog data to the child component
}
}
I was able to find a solution to the situation.
Problem Statement: I was trying to use the existing component (Let's call it ChildComponent) in 2 separate places. One as a regular child component and second, as a component inside Material Dialog.
Challenge: To pass data to the dialog component, we need @Inject(MAT_DIALOG_DATA) in the Child Component. But when you inject the ChildComponent inside the regular component, you don't provide any provider for the '@Inject(MAT_DIALOG_DATA)'. Hence, it fails while initiating. And we do need the '@Inject(MAT_DIALOG_DATA)' if we want to use the ChildComponent inside the Mat Dialog.
Solution: Create a wrapper component, let's call it (ChildWrapperComponent). For the regular use case, directly inject the ChildComponent in the parent component. Whereas for the Mat Dialog use case, provide the ChildWrapperComponent
const dialogRef = this.dialog.open(ChildWrapperComponent, {
width: '90%',
disableClose: false,
data: {
fileName: this.fileName,
results: this.results
}
} );
Now you can have the data inside the ChildWrapperComponent using @Inject(MAT_DIALOG_DATA) data
constructor(private spinner: EdpLoaderService, private dialog: MatDialog,
@Inject(MAT_DIALOG_DATA) data,
private dialogRef: MatDialogRef<ChildWrapperComponent>) {
this.setInputData(data);
}
Once you have the data inside the ChildWrapperComponent, inject the Child Component inside the Wrapper and pass data using @Input().
I am a newbie in Angular. Would highly appreciate better or different solutions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With