Nest can't resolve dependencies of AuthService

Sano picture Sano · Aug 25, 2020 · Viewed 9.3k times · Source

I am following the documentation present here

https://docs.nestjs.com/techniques/authentication#jwt-functionality

To have faster support I have created a git repository with the problem

https://github.com/Sano123456/nestjs-jwt

node -v -> v10.15.2
npm -v -> 6.14.6
nest -v -> 7.4.1

First Problem: in AuthModule if I do as described in documentation and just import UserModule, it return me error of circular dependency between UserModule and AuthModule

@Module({
  imports:[
    UsersModule,
    PassportModule
  ],
  providers: [AuthService],
  controllers: [AuthController],
  exports:[AuthService, LocalStrategy]
})
export class AuthModule {}

error:

[ExceptionHandler] Nest cannot create the AuthModule instance.
The module at index [0] of the AuthModule "imports" array is undefined.

Potential causes:
- A circular dependency between modules. Use forwardRef() to avoid it. Read more: https://docs.nestjs.com/fundamentals/circular-dependency
- The module at index [0] is of type "undefined". Check your import statements and the type of the module.

Scope [AppModule -> UsersModule] +6ms

Possibile solution in imports array of AuthModule instead of UserModule put forwardRef(() => UsersModule), this actually remove the error but not sure if this is the right way

Second problem: it says that can't find LocalStrategy class even if it's present and declared in AuthModule

[ExceptionHandler] Nest cannot export a provider/module that is not a part of the currently processed module (AuthModule). Please verify whether the exported LocalStrategy is available in this particular context.Is LocalStrategy part of the relevant providers/imports within AuthModule?

Possibile solution right now I don't have any solution, I just remove it to understand what is the problem

Third problem : after removing LocalStrategy,

[ExceptionHandler] Nest can't resolve dependencies of the AuthService (?). Please make sure that the argument dependency at index [0] is available in the AuthModule context.

Potential solutions:
- If dependency is a provider, is it part of the current AuthModule?
- If dependency is exported from a separate @Module, is that module imported within AuthModule?
  @Module({
    imports: [ /* the Module containing dependency */ ]
  })
 +1ms
Error: Nest can't resolve dependencies of the AuthService (?). Please make sure that the argument dependency at index [0] is available in the AuthModule context.

anyone solved this issues?

Answer

bashleigh picture bashleigh · Aug 25, 2020

You have a circular dependancy because your UsersModule and your AuthModule import each other. Therefore you have 2 options to repair this issue.

The first is to make a forward reference which will allow both modules to be built simultaneously and once built, pass in the reference required. This is done like so:

@Module({
  imports: [
    forwardRef(() => UsersModule),
  ],
  ...
})
export class AuthModule {}

// And the same for your UsersModule

@Module({
  imports: [
    forwardRef(() => AuthModule),
  ],
})
export class UsersModule {}

The second option is to remove the dependancies from one another. This is not always possible and guessing by the names of your modules I would argue this isn't possible. You don't want to have the auth module accessing the user module's database and services etc outside the users module. But I'll give you some advice on module inheritance.

Module in nestjs are built asynchronously. Meaning they have to be structured like a cascading tree with one module importing all the others. Something linear will look like this

AppModule <= CatModule <= PawsModule

Another example would be dual importing

            <= CatModule
AppModule                  <= PawsModule
            <= DogModule 

In the above example, the paws module is created once and imported in both cat and dog module. Meaning paws module will be built first before cat and dog module.

So to explain your error you need to think from a linear code perspective and how the module import tree will share modules that import each other. Because they import each other, nest can't decide which to create first so will need a reference to pass back, hence the function. I've always imagined the container's forward ref function as saying "Hey, hold this for a sec" (it's a piece of paper that says "UsersModule") then turns around, does some wavey of the arms with his back turned, then turns around and replaces the piece of paper with the UsersModule!

Your second issue is you never created a provider for LocalStrategy. It doesn't exist in the AuthModule so cannot be imported into AuthService nor exported from AuthModule!