ModuleRef.get(Symbol) don't work under some cases
See original GitHub issueBug Report
Current behavior
The order of console logs are unexpected đ ModuleRef returns an instance of the service without call its constructor.
Input Code
import { Inject, Injectable, Module, Optional } from '@nestjs/common';
import { ModuleRef } from '@nestjs/core';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Injectable()
class SpecialService {
constructor(public readonly service: AppService) {
console.log(`Hey! SpecialService here, my constructor has been called and the AppService is inyected correctly: `, service);
}
}
const SpecialSymbol = Symbol('Special Symbol');
// If you uncomment any of two comments below (or both), all works as expected
@Module({
controllers: [AppController],
providers: [AppService, /* SpecialService, */ { provide: SpecialSymbol, useClass: SpecialService }],
})
export class AppModule {
constructor(
@Optional() /* @Inject(SpecialSymbol) */ specialService: SpecialService,
private moduleRef: ModuleRef,
) {
// It works as expected...
// console.log(`from ModuleRef`, this.moduleRef.get(SpecialService))
console.log(`from ModuleRef`, this.moduleRef.get(SpecialSymbol))
console.log(`from DI`, specialService)
}
}
Repro: https://github.com/tonivj5/nestjs-bug-module-ref-symbol
- clone
- npm run start
- Play with the comments
Expected behavior
If you uncomment /* SpecialService, */
or /* @Inject(SpecialSymbol) */
it works as expected.
Possible Solution
IDK
Environment
Nest version: 8.0.6
For Tooling issues:
- Node version: latest
- Platform: Linux
Others:
Issue Analytics
- State:
- Created 2 years ago
- Comments:7 (3 by maintainers)
Top Results From Across the Web
ModuleRef.get(token, {strict: false}) does not inject ... - GitHub
When using ModuleRef to get providers there are situations when the instance returned does not have its own dependencies injected ...
Read more >Lazy-loading modules - A progressive Node.js framework
Hint Lazy-loaded modules cannot be registered as global modules as it simply makes no sense (since they are registered lazily, on-demand when all...
Read more >NestJS ModuleRef instances - node.js - Stack Overflow
I'm relatively new to nestJS and ran into a circular dependency with REQUEST Scoped services that got me reading about ModuleRef in nestJS....
Read more >How to fix "The following module is missing from the file ...
Then either go to the Modules page and disable/uninstall it from there, or use Drush ( drush dis module_name && drush pm-uninstall module_name...
Read more >How to Inject nestjs service from another module - Edureka
Both services are working alone in their module. ... I get this nest error : ... Do not add the same provider to...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Okay, I can see the
moduleRef.get
getting the service before the constructor is called with the current repo. Whatâs the use case where youâre using theModuleRef
to get the provider in the constructor instead of injecting the provider via the symbol?What I can tell is happening is that the
AppModule
class is being instantiated before theSpecialService
class, and theModuleRef
can see that thereâs thisSpecialSymbol
token and grabs it, but it doesnât have a value associated to it yet, itâs just an empty object.The reason it works properly when you uncomment
SpecialService
or@Inject(SpecialSymbol)
is because that optional dependency now actually exists in the container and Nest waits for it, but when you have@Optional()
if the provider doesnât exist at all, itâll just beundefined
as youâve seen.Thank you @jmcdo29 & @kamilmysliwiec! I understand that it doesnât work âby designâ, it makes sense.
Yeah, it should be used in a later hook (as
onModuleInit
)Thank you guys! đ