Search code examples
javascriptexpressnestjsbackendnest

Why nest js giving dependency injection error when i also imported modules in app module?


this is my codes:

Auth Module:

@Module({
  imports: [
    TypeOrmModule.forFeature([User]),
    JwtModule.register({
      secret: 'secret',
      signOptions: {
        expiresIn: '365d',
      }
    })
  ],
  controllers: [AuthController],
  providers: [AuthService],
})
export class AuthModule {}

Auth Controller:

@Controller("api")
export class AuthController {
  constructor(private readonly appService: AuthService, private readonly jwtService:JwtService ) {}
}

Auth Service:

@Injectable()
export class AuthService {
  constructor(@InjectRepository(User) private userRepo:Repository<User>) {}
}

Auth Guard:

@Injectable()
export class AuthGuard implements CanActivate {

  constructor(private readonly jwtService:JwtService,private readonly userService:AuthService) {}
  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    return ...
  }
}

App Module:

@Module({
  imports: [
    AuthModule,
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: '',
      database: 'nestjs',
      entities: [User,Post],
      synchronize: true,
    }),
    TypeOrmModule.forFeature([Post]),
  ],
  controllers: [PostController],
  providers: [PostService],

})
export class AppModule{}

And i have this error: Nest can't resolve dependencies of the AuthGuard (?, AuthService). Please make sure that the argument JwtService at index [0] is available in the AppModule context .

i defined jwt service in auth module and i imported auth module in app module, but the error says i should import jwt service in app module, why?

i also checked my imports in app module


Solution

  • I'm going to assume that in the AppModule's PostController you are using this AuthGuard class via @UseGuards(AuthGuard). When you do this, Nest will try to create an instance of that guard in the context of the current controller's module (in this case AppModule). For that to happen, Nest will look at the parameters of the AuthGuard and pull them from the module's context, first by looking at immediate providers, then looking at the exports of the modules in the imports array. If those providers are not found, an error will be thrown.

    In your case, in your AuthModule you should add AuthService and JwtModule to the exports array, to provide access to AuthService directly, and to provide access to JwtService via Module Re-exporting. Your final AuthModule should look something like this:

    @Module({
      imports: [
        TypeOrmModule.forFeature([User]),
        JwtModule.register({
          secret: 'secret',
          signOptions: {
            expiresIn: '365d',
          }
        })
      ],
      controllers: [AuthController],
      providers: [AuthService],
      exports: [AuthService, JwtModule],
    })
    export class AuthModule {}
    

    Now, in whatever controller class you need to use this AuthGuard, make sure to add AuthModule to the controller's module's imports, and you should be good to go.