angular: Eager providers and Injector.get() can cause errors
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
After updating from 4.0.0-rc.2
to 4.0.0
Router
not injected as expected
Expected behavior
Should be injected as expected
Minimal reproduction of the problem with instructions
Plunker: http://plnkr.co/edit/ogCHjeYuCDM8vNLdwAFx?p=preview
Update from 4.0.0-rc.2
to 4.0.0
ConfigService
provided in AppModule
as APP_INITIALIZER
providers: [
ConfigService,
{
provide: APP_INITIALIZER,
useFactory: configServiceFactory,
deps: [ConfigService],
multi: true
}
],
ApiService
injected manually from ConfigService
@Injectable()
export class ConfigService {
private api: ApiService;
public constructor(
private injector: Injector
) {
// Avoid cyclid dependencies, inject manually:
this.api = injector.get(ApiService);
}
router
is undefined when injected in ApiService
import { Http, Headers, RequestOptionsArgs, Response } from '@angular/http';
import { Router } from '@angular/router';
@Injectable()
export class ApiService {
constructor(
private router: Router,
private http: Http
) {
console.log(router, 'router'); // undefined
debugger;
What is the motivation / use case for changing the behavior?
Please tell us about your environment:
@angular/cli: 1.0.0 node: 7.4.0 os: win32 x64 @angular/animations: 4.0.0 @angular/common: 4.0.0 @angular/compiler: 4.0.0 @angular/compiler-cli: 4.0.0 @angular/core: 4.0.0 @angular/forms: 4.0.0 @angular/http: 4.0.0 @angular/platform-browser: 4.0.0 @angular/platform-browser-dynamic: 4.0.0 @angular/platform-server: 4.0.0 @angular/router: 4.0.0 @angular/material: 2.0.0-beta.2 @angular/flex-layout: 2.0.0-rc.1 @angular/cli: 1.0.0 @ngtools/webpack: 1.3.0
- Angular version: 4.0.0
-
Browser: all
-
Language: TypeScript 2.2.1
-
Node (for AoT issues):
node --version
= 7.4.0
The log given by the failure.
core.es5.js:1085 ERROR TypeError: Cannot read property 'url' of undefined
at CatchSubscriber.selector (api.service.ts:127)
at CatchSubscriber.error (catch.js:104)
at MapSubscriber.Subscriber._error (Subscriber.js:128)
at MapSubscriber.Subscriber.error (Subscriber.js:102)
at XMLHttpRequest.onLoad (http.es5.js:1210)
at ZoneDelegate.invokeTask (zone.js:363)
at Object.onInvokeTask (core.es5.js:4136)
at ZoneDelegate.invokeTask (zone.js:362)
at Zone.runTask (zone.js:166)
at XMLHttpRequest.ZoneTask.invoke (zone.js:416)
defaultErrorLogger @ core.es5.js:1085
ErrorHandler.handleError @ core.es5.js:1145
next @ core.es5.js:4774
schedulerFn @ core.es5.js:3848
SafeSubscriber.__tryOrUnsub @ Subscriber.js:234
SafeSubscriber.next @ Subscriber.js:183
Subscriber._next @ Subscriber.js:125
Subscriber.next @ Subscriber.js:89
Subject.next @ Subject.js:55
EventEmitter.emit @ core.es5.js:3834
NgZone.triggerError @ core.es5.js:4205
onHandleError @ core.es5.js:4166
ZoneDelegate.handleError @ zone.js:334
Zone.runTask @ zone.js:169
ZoneTask.invoke @ zone.js:416
Navigated to http://localhost:4200/
core.es5.js:3053Template parse warnings:
The <template> element is deprecated. Use <ng-template> instead ("[WARNING ->]<template><div class="mat-autocomplete-panel" role="listbox" [id]="id" [ngClass]="_getClassList()" #p"): ng:///MdAutocompleteModule/MdAutocomplete.html@0:0
Console.warn @ core.es5.js:3053
TemplateParser.parse @ compiler.es5.js:11508
JitCompiler._compileTemplate @ compiler.es5.js:25195
(anonymous) @ compiler.es5.js:25119
JitCompiler._compileComponents @ compiler.es5.js:25119
createResult @ compiler.es5.js:25004
ZoneDelegate.invoke @ zone.js:330
Zone.run @ zone.js:126
(anonymous) @ zone.js:679
ZoneDelegate.invokeTask @ zone.js:363
Zone.runTask @ zone.js:166
drainMicroTaskQueue @ zone.js:529
api.service.ts:31 undefined "router"
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 7
- Comments: 18 (3 by maintainers)
Commits related to this issue
- amend: support injecting a lazy provider via `Injector.get` in an eager provider. The previous way of generating code for `NgModule` supported this case, so we also need to support it now. I fixed i... — committed to tbosch/angular by tbosch 7 years ago
- fix(compiler): correctly instantiate eager providers that are used via `Injector.get` This also fixes the problem that all `NgModule` instances became lazy when using `TestBed.overrideProvider`. Clo... — committed to tbosch/angular by tbosch 7 years ago
- fix(compiler): correctly instantiate eager providers that are used via `Injector.get` This also fixes the problem that all `NgModule` instances became lazy when using `TestBed.overrideProvider`. Clo... — committed to tbosch/angular by tbosch 7 years ago
- fix(compiler): correctly instantiate eager providers that are used via `Injector.get` This also fixes the problem that all `NgModule` instances became lazy when using `TestBed.overrideProvider`. Clo... — committed to tbosch/angular by tbosch 7 years ago
- fix(compiler): correctly instantiate eager providers that are used via `Injector.get` This also fixes the problem that all `NgModule` instances became lazy when using `TestBed.overrideProvider`. Clo... — committed to tbosch/angular by tbosch 7 years ago
- fix(compiler): correctly instantiate eager providers that are used via `Injector.get` This also fixes the problem that all `NgModule` instances became lazy when using `TestBed.overrideProvider`. Not... — committed to tbosch/angular by tbosch 7 years ago
- fix(compiler): correctly instantiate eager providers that are used via `Injector.get` This also fixes the problem that all `NgModule` instances became lazy when using `TestBed.overrideProvider`. Not... — committed to tbosch/angular by tbosch 7 years ago
- fix(compiler): correctly instantiate eager providers that are used via `Injector.get` This also fixes the problem that all `NgModule` instances became lazy when using `TestBed.overrideProvider`. Not... — committed to tbosch/angular by tbosch 7 years ago
- fix(compiler): correctly instantiate eager providers that are used via `Injector.get` This also fixes the problem that all `NgModule` instances became lazy when using `TestBed.overrideProvider`. Not... — committed to tbosch/angular by tbosch 7 years ago
- fix(compiler): correctly instantiate eager providers that are used via `Injector.get` Closes #15501 — committed to tbosch/angular by tbosch 7 years ago
- fix(compiler): correctly instantiate eager providers that are used via `Injector.get` (#19558) Closes #15501 PR Close #19558 — committed to angular/angular by tbosch 7 years ago
Any update ???
When would this bug be fixed? I’m still facing the issue. Please notify
I use this :
I was blocked also but was able to work around this issue with AOT by following https://github.com/angular/angular-cli/issues/5762#issuecomment-295670906. Injecting the injector into my service used with APP_INITIALIZER and waiting for it to be initialized.
import { LOCATION_INITIALIZED } from ‘@angular/common’; import { Injectable, Injector } from ‘@angular/core’; import { Http } from ‘@angular/http’;
// Services import { AnalyticsService } from ‘./services/analytics.service’; import { SettingsService } from ‘./services/settings.service’;
@Injectable() export class AppConfigService { private isInit = false;
}
Here you go. Open console
http://plnkr.co/edit/ogCHjeYuCDM8vNLdwAFx?p=preview