Reputation: 353
I have AngularJS application and i am trying to make hybrid app but not able to use AngularJS service insight Angular component : getting error
ERROR Error: Trying to get the AngularJS injector before it being set.
my main.ts is
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
platformBrowserDynamic().bootstrapModule(AppModule);
app.module :
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, InjectionToken } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { UpgradeModule, downgradeComponent } from '@angular/upgrade/static';
import { AppComponent } from './app.component';
import { SignInComponent } from "./modules/login/components/sign-in/sign-in.component";
import { authServiceProvider } from './shared/angularJS-upgraded-providers';
@NgModule({
declarations: [
AppComponent,
SignInComponent
],
imports: [
BrowserModule,
UpgradeModule,
FormsModule
],
entryComponents: [
SignInComponent
],
providers: [authServiceProvider],
bootstrap: [SignInComponent]
})
export class AppModule {
ngDoBootstrap() {}
}
angularJS-upgraded-providers.ts :
import { InjectionToken } from "@angular/core";
export const AuthService = new InjectionToken<any>('authService');
export function authServiceFactory(i: any) {
return i.get('authService');
}
export const authServiceProvider = {
provide: AuthService,
useFactory: authServiceFactory,
deps: ['$injector']
};
and sign-in.component.ts :
import { Component, Inject } from '@angular/core';
import {AuthService} from "../../../../shared/angularJS-upgraded-providers";
@Component({
selector: 'sign-in',
template: require('./sign-in.component.html')
})
export class SignInComponent {
constructor(
@Inject(AuthService) private authService: any) {
}
}
When I remove SignInComponent constructor part code compiles well but with @Inject(AuthService) private authService: any) { } part I am getting an error :
Trying to get the AngularJS injector before it being set.
Please give me some suggesting how can I implement angularJS service insight Angular component. Thanks
P.S. my package.json :
{
"name": "test",
"version": "1.0.0",
"private": true,
"scripts": {
"start": "webpack-dev-server --port=4200 --open chrome"
},
"dependencies": {
"@angular/common": "^5.2.11",
"@angular/compiler": "^5.2.11",
"@angular/core": "^5.2.11",
"@angular/forms": "^5.2.11",
"@angular/http": "^5.2.11",
"@angular/platform-browser": "^5.2.11",
"@angular/platform-browser-dynamic": "^5.2.11",
"@angular/router": "^5.2.11",
"@angular/upgrade": "^5.2.11",
"core-js": "^2.5.7",
"reflect-metadata": "^0.1.12",
"rxjs": "^5.5.11",
"zone.js": "^0.8.26"
},
"devDependencies": {
"@types/jquery": "^3.3.6",
"@types/node": "^8.10.23",
"awesome-typescript-loader": "^5.2.0",
"css-loader": "^1.0.0",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.2.0",
"raw-loader": "^0.5.1",
"style-loader": "^0.22.1",
"ts-loader": "3.2.0",
"typescript": "^2.9.2",
"webpack": "^4.16.5",
"webpack-cli": "^3.1.0",
"webpack-dev-server": "^3.1.5"
}
}
And AngularJS version : 1.6.8
Upvotes: 6
Views: 3942
Reputation: 3298
For anyone struggling with this is 2024, here are two options
export class MyComponent {
private readonly upgrade = inject(UpgradeModule);
private readonly authService = this.upgrade.$injector.get("authService");
}
import * as angular from 'angular'; // import AngularJS
export const appConfig: ApplicationConfig = {
providers: [
{
provide: AuthService,
useFactory: () => {
const injector = angular.injector(["ng", "auth.module"]); // Replace "auth.module" with the name of the AngularJS module the service belongs to.
return injector.get("authService");
}
},
{
provide: APP_INITIALIZER,
useFactory: (authService: AuthService) => (): void => {
// use authService
},
deps: [AuthService],
multi: true
}
]
};
Upvotes: 0
Reputation: 4342
This means you are pulling in an AngularJS dependency somewhere in your component tree. It may be in your immediate component or some dependency further down the line.
To debug:
Method 1
Add a debugger
statement immediately before your bootstrap
call:
it('should render the component', () => {
debugger;
bootstrap(Ng2AppComponent);
...
});
injectorFactory
. Use the stack explorer to find calls to resolveNgModuleDep
. These will be recursive, so the top of the stack will be closer to a leaf node, while calls further down the stack will be closer to your component being tested. Look for lines like: tokenKey = "ServiceName"
. This is potentially your offending service. beforeEach(() => {
setupModule({
imports: [
...
],
providers: [
{
provide: '$injector',
useValue: {
get: () => {
return new MockService(); // enhance as needed
},
}
}
],
});
Method 2
$injector
call, and return an empty object. beforeEach(() => {
setupModule({
imports: [
...
],
providers: [
{
provide: '$injector',
useValue: {
get: (serviceName?: string) => {
console.log('looking for serviceName:', serviceName);
return {}; // this will break things differently
},
}
}
],
});
Upvotes: 4