Closed dexster closed 9 months ago
Thanks for the issue! This issue has been labeled as needs reproduction
. This label is added to issues that need a code reproduction.
Please reproduce this issue in an Ionic starter application and provide a way for us to access it (GitHub repo, StackBlitz, etc). Without a reliable code reproduction, it is unlikely we will be able to resolve the issue, leading to it being closed.
If you have already provided a code snippet and are seeing this message, it is likely that the code snippet was not enough for our team to reproduce the issue.
For a guide on how to create a good reproduction, see our Contributing Guide.
Repro here.
Open the console to view the error. Follow the comments in the main.ts and app.routes.ts
Thanks for the repo. I can reproduce the reported issue, but this is not a bug in Ionic Framework. Adding the provider on the route level breaks inside of the modal because modals are intentionally created outside of any routing. These components are temporary views and are dependent on the presenting context. Adding the provider in main.ts
works because the injection token is in the same context that the modal is in.
In terms of avoiding this error, I recommend providing the token in main.ts
. Alternatively, you can use the options
parameter to define a factory for the token: https://angular.io/api/core/InjectionToken#constructor
@liamdebeasi I understand this is not an Ionic bug but I do believe this functionality is critical going forward. With the prevalence of micro frontends and standalone apps in Angular this could be a blocker for many apps.
The alternatives suggested are not possible as my app is a remote app inside a micro frontend shell app. Adding providers in the entry route is how the app bootstraps when using a standalone app (previously a module would be passed to the shell app). Asking the owners of the shell app to add my providers is not feasible
The injection token I used above was just for repro purposes, the actual one in my app sits in a 3rd party lib so I cannot modify it.
I believe the solution I provided in my original comment, where we can pass the injection context, could work. I modified the Ionic code and tested it and it solved my issue. I could attempt a proper fix with a PR?
Angular Material provides this option with the injector property in their dialog. https://material.angular.io/components/dialog/api#MatDialogConfig
Are you able to use an inline modal instead of a controller modal?
Not in this case. We create reusable modals using the controller
@liamdebeasi we're experiencing the similar issue. Do you plan to add injector
option to ModalController
?
Update. I just found workaround that works for us.
In our case it started to occur after migrating to ionic standalone components. Previously importing IonicModule
in lazily loaded module was good enough.
As we moved to standalone components adding ModalController
to list of providers in lazily loaded module seems to fix the issue.
If you plan to investigate it deeper here's an example from ng-bootstrap
library that seems to handle injectors better:
https://github.com/ng-bootstrap/ng-bootstrap/blob/b5d5febde5691286211dd2401c2cb5334db0851f/src/modal/modal-stack.ts#L86-L88
Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out.
Prerequisites
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.Steps to Reproduce
export const remoteRoutes: Route[] = [ { path: '', providers: [{provide: TEST_DIALOG, useValue: 'test'}], loadComponent: () => import('./dialog.component').then(m => m.DialogComponent) } ];
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