ionic-framework
ionic-framework copied to clipboard
bug: Angular NullInjector when referencing Injection Tokens in modal components
Prerequisites
- [X] I have read the Contributing Guidelines.
- [X] I agree to follow the Code of Conduct.
- [X] I have searched for existing issues that already report this problem, without success.
Ionic Framework Version
v7.x
Current Behavior
When an InjectionToken is provided in a context that is not the root context, it is not available in a component created using the ModalController. A NullInjector error is thrown.
Expected Behavior
The token should be available in components created via ModalController.
An injection parameter could be added to the modal options. Modifying the create method like this fixed the issue for me.
create(opts) {
return super.create({
...opts,
// added the opts.injector.
delegate: this.angularDelegate.create(this.environmentInjector, opts.injector || this.injector, 'modal'),
});
}
// In the component
private environmentInjector = inject(EnvironmentInjector);
constructor(private modalCtrl: ModalController) { }
async openModal() {
const modal = await this.modalCtrl.create({
component: ModalExampleComponent,
injector: this.environmentInjector
});
Steps to Reproduce
- Create an InjectionToken and add it to a route provider
export const TEST_DIALOG = new InjectionToken('TEST_DIALOG');
export const remoteRoutes: Route[] = [
{
path: '',
providers: [{provide: TEST_DIALOG, useValue: 'test'}],
loadComponent: () => import('./dialog.component').then(m => m.DialogComponent)
}
];
- Open a modal that uses the token
@Component({
selector: 'my-lib',
standalone: true,
imports: [CommonModule],
template: `
<button (click)="openModal()">Open</button>`,
})
export class DialogComponent {
private environmentInjector = inject(EnvironmentInjector);
constructor(private modalCtrl: ModalController) {}
async openModal() {
const modal = await this.modalCtrl.create({
component: ModalExampleComponent,
});
modal.present();
}
}
@Component({
selector: 'my-lib',
standalone: true,
imports: [CommonModule],
template: `
<button (click)="openModal()">Open</button>`,
})
export class DialogComponent {
constructor(private modalCtrl: ModalController) {
}
async openModal() {
const modal = await this.modalCtrl.create({
component: ModalExampleComponent
});
modal.present();
}
}
@Component({
selector: 'my-modal',
template: `<h1>dialog</h1>`,
standalone: true
})
export class ModalExampleComponent {
// nullinjector error thrown here
testDialog = inject(TEST_DIALOG);
constructor() {
console.log('TEST DIALOG: ', this.testDialog);
}
}
Code Reproduction URL
No response
Ionic Info
Ionic:
Ionic CLI : 7.2.0
Utility:
cordova-res : not installed globally native-run : not installed globally
System:
NodeJS : v20.9.0 npm : 10.1.0 OS : macOS Unknown
Additional Information
No response