angular: angular/upgrade static $injector is undefined when upgrading ng1 service
I’m submitting a … (check one with “x”)
[x] bug report => search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
Current behavior I cannot inject an upgraded ng1 service into a ng2 component. Because $injector is undefined.
Expected behavior I can inject the upgraded ng1 service
Minimal reproduction of the problem with instructions If I use an angular2 component as root (as described here: https://angular.io/docs/ts/latest/guide/upgrade.html#!#dividing-routes-between-angular-and-angularjs) I get the $injector issue (as shown in the plnkr bellow) ONLY if the “initial route (/login)” is an angular2 route. If I start with an angular1 route and then change to the angular2 route (/login) everything works fine. https://plnkr.co/edit/mUvt7miMrOEyTyEk8ooX?p=preview
What is the motivation / use case for changing the behavior? To use angular1 services within an angular2 context while gradually moving towards an angular2 application.
Please tell us about your environment: OS: Windows 10 IDE: Webstorm Package manager: NPM, Build system: Webpack, Webserver: webpack-dev-server
-
Angular version: 2.0.X 2.4.1
-
Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ] Chrome
-
Language: [all | TypeScript X.X | ES6/7 | ES5] Typescript 2.2.1
-
Node (for AoT issues):
node --version
=
6.1
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 2
- Comments: 20 (9 by maintainers)
This happens, because
upgrade/static
expects that each upgraded component will be in the template of a downgraded component (which would be true if you had downgraded theRootComponent
). But this might not work with the routing setup you have.From a quick look, you could add a provider for
$scope
(which the upgradedNg1FooDirective
will look for) pointing it to the$rootScope
:This works for you updated plnkr, but - again - might break for more complex usecases 😃
This is expected (in a way), because the bootstrapped component gets instantiated before bootstrapping the AngularJS part (and therefore the AngularJS
$injector
has not been created yet). We are looking into some ways to overcome such limitations. There are also some subtle zone-related issues with bootstrapping AngularJS in thebootstrapModule().then
(the relevant docs will be revised soon).In your’s plnkr’s simple usecase you can bootstrap AngularJS inside the
AppModule
’s constructor (updated plnkr), but it is possible that the solution is not as straight forward in more complex scenarios:This is not recommended, because it will bootstrap the hybrid app outside of the Angular zone, so some things (mostly related to change detection) might not work as expected.
Remove bootstrap from @NgModule. Add bootstrap in main.ts file-
platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => { const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule; upgrade.bootstrap(document.body, [‘myApp’], { strictDi: true }); });
@gkalpak, thank you for solution. I had same issue but now I have exception
No provider for $scope!
when I am trying to use upgraded component in angular 2 template. Updated plunker here Is it one of more complex scenario that you mentioned? Any workarounds for this case?@gkalpak i created a new angular cli project and copy the files from this plunker https://plnkr.co/edit/Okwv7K4JOJZl8MWJyaXh?p=preview and is not working , im still facing the $injector problem, when calling the super inside the
export class Ng1FooDirective extends UpgradeComponent { constructor(elementRef: ElementRef, injector: Injector) { super('ng1FooComponent', elementRef, injector); } }
this is the repo : https://github.com/correasebastian/ng1c2ng2d ,any help will be really appreciate