Reputation: 31
everyone. I need help with such problem.
I have such code for my angular 1.x app.js:
angular.module('app', []);
angular.module('app.test', ['app'])
.config(($stateProvider) =>
$stateProvider.state('base', {
url: '/',
controller: 'TestStateCtrl',
resolve: {
authenticationCheck: ['angularNg1Service', angularNg1Service=> {
angularNg1Service.test1();
}]
}
})
})
.run((angularNg1Service) => {
angularNg1Service.test2();
});
Here is the code of my angularNg1Service:
angular.module('app')
.service('angularNg1Service',
function (angularNg2Service} {
//some code here
}
My angularNg2Service is downgraded before .run
function of angular 1.x module starts:
window['angular']
.module('app')
.factory(
'angularNg2Service',
upgradeAdapter.downgradeNg2Provider(AngularNg2Service)
);
But, I have an error message :
Cannot read property 'injector' of null
When .run
function of angular 1.x module starts.
Here is my main.ts file:
import { upgradeAdapter } from './upgradeAdapter';
import { bootstrapNg1Components } from './app/ng1Components';
bootstrapNg1Components(upgradeAdapter);// this function downgarades my AngularNg2Service
upgradeAdapter.bootstrap(document.querySelector('html'), ['app.start']);
I have read some similar problems but don't find any solution.
Also I have a lot of Angular2 Services which are downgraded.But the problem is just for one particular service that is injected into Angular1 Service that is used in .run
function.
Upvotes: 3
Views: 272
Reputation: 11
You can use workaround described here https://github.com/angular/angular/issues/10992: put your run code in setTimeout function.
angular.module('app.test', ['app'])
...
.run(($injector) => {
setTimeout(function() {
var angularNg1Service = $injector.get('angularNg1Service');
angularNg1Service.doSmth();
// downgraded angularNg2Service is available here
// inside of async function that will run after module.run method
var angularNg2Service = $injector.get('angularNg2Service');
},0);
});
To be sure the application state does not start before application is configured (that performed in run method) you can add resolve for every state.
angular.module('app.test', ['app'])
.config(($stateProvider) =>
$stateProvider.state('base', {
url: '/',
controller: 'TestStateCtrl',
resolve: {
appBootstrapped: ['appBootstrapStateService', () => {
return appBootstrapStateService.statePromise;
]},
authenticationCheck: ['angularNg1Service', 'appBootstrapped', (angularNg1Service, appBootstrapped) => {
angularNg1Service.test1();
}]
}
})
})
And to make it works you should change bootstraped state at the end of module.run method
angular.module('app.test', ['app'])
...
.run(($injector) => {
setTimeout(function() {
...
var appBootstrapStateService = $injector.get('appBootstrapStateService');
appBootstrapStateService.complete(); // allow state work
},0);
});
appBootstrapStateService is angularJS service like
angular.module('app')
.service('appBootstrapStateService', function () {
const stateSubject = new Rx.Subject();
this.statePromise = stateSubject.asObservable().toPromise();
this.complete = () => {
stateSubject.complete();
};
});
Upvotes: 1