angular: New `provideIn: AppModule` syntax not working
I’m submitting a…
[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report <!-- Please search GitHub for a similar issue or PR before submitting -->
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
[ ] Other... Please describe:
Current behavior
When using the new provideIn
syntax for injectable services as documented on https://angular.io/guide/dependency-injection#injectable-providers:
@Injectable({
providedIn: AppModule,
})
export class HeroService {
}
And request the service in a component:
@Component({})
export class AppComponent {
title = 'app';
constructor(s: HeroService) { }
}
I get this error:
ERROR Error: StaticInjectorError(AppModule)[AppComponent -> HeroService]:
StaticInjectorError(Platform: core)[AppComponent -> HeroService]:
NullInjectorError: No provider for HeroService!
Expected behavior
I would expect the service to be injected as singleton for the entire AppModule
Minimal reproduction of the problem with instructions
https://stackblitz.com/edit/angular-ggecbg
What is the motivation / use case for changing the behavior?
I’m trying to figure out how to provide a service as a singleton in a single module using the new provideIn
syntax. It is documented here: https://angular.io/guide/dependency-injection#injectable-providers but does not seem to work. Or I’m I making a mistake?
Environment
Angular version: X.Y.Z
Browser:
- [x] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
For Tooling issues:
- Node version: 10.1.0
- Platform: windows
- Angular CLI: 6.0.3
- Angular: 6.0.2
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 48 (30 by maintainers)
Links to this issue
Commits related to this issue
- feat(core): better error message for "providedIn: undefined" case closes #24082 — committed to trotyl/angular by trotyl 6 years ago
- feat(core): better error message for "providedIn: undefined" casecloses #24082 — committed to trotyl/angular by trotyl 6 years ago
- feat(core): better error message when providedIn target being undefined closes #24082 — committed to trotyl/angular by trotyl 6 years ago
- feat(core): better error message when providedIn target being undefinedcloses #24082 — committed to trotyl/angular by trotyl 6 years ago
- feat(core): better error message when providedIn target being undefined closes #24082 — committed to trotyl/angular by trotyl 6 years ago
- feat(core): better error message when providedIn target being undefined closes #24082 — committed to trotyl/angular by trotyl 6 years ago
- feat(core): better error message when providedIn target being undefined closes #24082 — committed to trotyl/angular by trotyl 6 years ago
@nicojs ES modules support circular dependency ONLY when it’s not used eagerly, but all metadata were used eagerly.
A simple
console.log
could help you confirm what the problem is: https://stackblitz.com/edit/angular-xghrcp?file=src/app/hero.service.ts. It’s indeed anundefined
value and being skipped by Angular.So it’s not a problem of Angular, from Angular’s perspective, you just wrote:
Angular CLI already provides
--show-circular-dependencies
functionality, every time a circular dependencies occurs, you need to fix it first, rather than just believing it won’t break anything.@gkalpak The value of
providedIn
has nothing to do with loading/bundling, only determines whether it is ALLOWED to use after being loaded.And
providedIn: 'root'
means allowed anywhere.@nicojs I’ve seen these things come and expressed my concerns here when Angular v6 wasn’t even released. But I think we should assume the Angular authors have had their reasons for why they designed the API this way.
In fact the docs say:
What the docs or migration guide should make clear, though, is that a
module-[provides]->service
relationship shouldn’t be systematically migrated to the inverseservice-[providedIn]->module
relationship but ontoservice-[providedIn]->"root"
(see the linked issue thread).@kapunahelewong Thanks, it’s really helpful!
@kumaran-is … did you read https://github.com/angular/angular/issues/25784 ? The key point of the theme are cases as:
https://github.com/angular/angular/issues/25784#issuecomment-417919896 https://github.com/angular/angular/issues/25784#issuecomment-418514688
… so you need always
additional module
. Otherwise, you havefeatureModule
asundefined
.@jbogarthyde thanks for your work.
I think the warning already helps people. What I’m still missing why you would want to use
provideIn: MyModule
. Is there any use case for that?@trotyl If we provide all service in
'root'
instead of theLazyLoadedModule
, won’t it increase the initial bundle size?? Or since these are tree shakable will it be bundled only with the module that actually uses it??From Angular side, it shouldn’t use
options.providedIn !== undefined
but'providedIn' in options
(need to make it closure-safe) to detect possible circular-dep issue, that way it could produce a better error message.Ref: https://github.com/angular/angular/blob/13cb75da8b02ed7aa60508dbb5ecd9065809fd12/packages/core/src/di/injectable.ts#L117