question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

ModuleRef.get(Symbol) don't work under some cases

See original GitHub issue

Bug Report

Current behavior

image 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. image

Possible Solution

IDK

Environment


Nest version: 8.0.6

 
For Tooling issues:
- Node version: latest  
- Platform: Linux 

Others:

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
jmcdo29commented, Aug 12, 2021

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 the ModuleRef 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 the SpecialService class, and the ModuleRef can see that there’s this SpecialSymbol 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 be undefined as you’ve seen.

1reaction
tonivj5commented, Aug 23, 2021

Thank you @jmcdo29 & @kamilmysliwiec! I understand that it doesn’t work “by design”, it makes sense.

Just to add my 2 cents here, you should never use moduleRef within the constructor, it’s not designed to be used there.

Yeah, it should be used in a later hook (as onModuleInit)

Thank you guys! 😃

Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found