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.2About 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.logcould help you confirm what the problem is: https://stackblitz.com/edit/angular-xghrcp?file=src/app/hero.service.ts. It’s indeed anundefinedvalue 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-dependenciesfunctionality, 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
providedInhas 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]->servicerelationship shouldn’t be systematically migrated to the inverseservice-[providedIn]->modulerelationship 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 havefeatureModuleasundefined.@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 !== undefinedbut'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