I have a very large hybrid Angular app; the original app is angularjs 1.6.8 while the rest is Angular 7.2.15. We are working to convert the entire app to Angular, but it is slow going. Our app also relies on angular-ui-bootstrap (2.5.0) / ngx-bootstrap (3.1.3).
Each of our significant views are lazy loaded with the exception of the landing page. I am currently attempting to convert one of those views.
Our App module imports ModalModule.forRoot()
. This works well until I try to access it in a downgraded service. For example, I have a route named "Account" with a service name AccountModalService
with this downgrade created:
import angular from 'angular';
import { downgradeInjectable } from '@angular/upgrade/static';
import { AccountModalService as service } from './accountModal.service';
angular.module('account').factory('AccountModalService', downgradeInjectable(service));
Now from my angularjs AccountPage
I should be able to open a modal like so
const accountPage = {
controller: AccountPageCtrl,
template: `<div><button ng-click="test()">Test</button></div>`
};
AccountPageCtrl.$inject = [
'AccountModalService'
];
function AccountPageCtrl(AccountModalService) {
this.test = function test() {
AccountModalService.openTestModal(); // this would open my test modal
};
}
angular.
module('account').
component('accountPage', accountPage);
I know the modal works when the openTestModal
method is called from an Angular Component, but when I attempt to launch it from an angularjs component. I get the error
angular.js:14800 Error: StaticInjectorError(AppModule)[AccountModalService]:
StaticInjectorError(Platform: core)[AccountModalService]:
NullInjectorError: No provider for AccountModalService!
If I change AccountModalService
to exist on the root injector, like so @Injectable({ provideIn: 'root' })
, I get an error indicating that the injector can not find the component that the modal is intended to display:
angular.js:14800 Error: No component factory found for TestModalComponent. Did you add it to @NgModule.entryComponents?
at noComponentFactoryError (core.js:9877)
...
The TestModalComponent
is an entryComponent
of the lazy loaded AccountModule
and that module imports my eagerly loaded common module. But sure enough, TestModalComponent
is not an entryComponent
of the AppModule
.
If I move my test modal component and this service into the eager loaded code, it will properly open the modal. However, this is just the first step in making the eager loaded module a monolith. It is not a pattern I want to continue as it makes lazy loaded routes worthless.
Is there any way to downgrade an angular service that uses the ngx-bootstrap modal BsModalService
to show a modal from angularjs code in an lazy loaded route? Has anyone successfully done something similar who is willing to share how?