I'm trying to read a query param on a given route in the canActivate
function and if it's not there, show a modal saying that it's not going to work ok.
When I think more about this, because it's only supposed to happen when the app is started for the first time, I think I'll move the logic in a provider with APP_INITIALIZER.
That said, I'm quite frustrated that I haven't been able to inject the MAT_DIALOG_DATA
properly and I'd like to:
Before I share a minimal repro, let me walk you through the code I wrote:
bootstrapApplication(App, {
providers: [
importProvidersFrom(MatDialogModule),
provideRouter([
{
path: '',
component: FooComponent,
canActivate: [
() => {
const dialog = inject(MatDialog);
dialog.open(DialogComponent, {
data: {
helloWorld: true,
},
});
return true;
},
],
},
]),
],
});
I make sure to import MatDialogModule
and then I define a dummy route to have a canActivate
. In here, I open up a dialog in which I try to pass some data.
The dialog component is defined as the following:
export class DialogComponent {
@Inject(MAT_DIALOG_DATA) public dialogData: any;
}
and the view
Data received in the dialog:
<pre>{{ dialogData | json }}</pre>
The issue being that dialogData
is always undefined here.
I suspect that from the canActivate
, I get a different injector and it's somehow messing up with this idea of launching a dialog with data from here. But it should be as easy as swapping the injector? Or even overriding manually the injector to define the MAT_DIALOG_DATA
token myself?
Well I've tried that too, and it doesn't work:
const newInjector = Injector.create({
providers: [
{
provide: MAT_DIALOG_DATA,
useValue: {
helloWorld: true,
},
},
],
parent: inject(Injector),
});
dialog.open(DialogComponent, {
data: {
helloWorld: true,
},
injector: newInjector
});
I have also tried passing the ViewContainerRef
out of desperation but I did not expect that to work.
What am I missing here? Can anyone explain and give a workaround?
Here's a Stackblitz repro.
EDIT:
I just tried to migrate my code to the APP_INITIALIZER
and I've got the exact same issue, so I'm out of options.
Please update the dialog component code, we need to use the injector inside the constructor for dependency injection to work I think!
import { CommonModule } from '@angular/common';
import { Component, Inject, OnInit } from '@angular/core';
import { MatDialogModule, MAT_DIALOG_DATA } from '@angular/material/dialog';
@Component({
selector: 'app-dialog',
templateUrl: './dialog.component.html',
styleUrls: ['./dialog.component.css'],
standalone: true,
imports: [CommonModule, MatDialogModule],
})
export class DialogComponent {
public dialogData: any;
constructor(@Inject(MAT_DIALOG_DATA) private data: any) {
this.dialogData = data;
}
}