Home > Mobile >  Error: Nest can't resolve dependencies of the CanModifyGuard (UsersService, ?)
Error: Nest can't resolve dependencies of the CanModifyGuard (UsersService, ?)

Time:11-12

just when I thought I do understand how the modules work and starting to play with guards which leads me to this error in full

Error: Nest can't resolve dependencies of the CanModifyGuard (UsersService, ?). Please make sure that the argument TelevisionsService at index [1] is available in the UsersModule context.

Potential solutions:
- If TelevisionsService is a provider, is it part of the current UsersModule?
- If TelevisionsService is exported from a separate @Module, is that module imported within UsersModule?
  @Module({
    imports: [ /* the Module containing TelevisionsService */ ]
  })

CanModifyGuard was fine when the guard is using only TelevisionsService, once I added the UsersService and add the guard into the UsersController The error above popped up.

Wonder if I can have another pair of eyes where I am setting this wrong?

app.module.ts

import { MiddlewareConsumer, Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { MongooseModule } from '@nestjs/mongoose';
import { ConfigModule } from '@nestjs/config';
import { UsersModule } from './resources/users/users.module';
import { AuthModule } from './resources/auth/auth.module';
import { CommonModule } from './resources/common/common.module';
import { TelevisionsModule } from './resources/televisions/televisions.module';
import { CurrentUserMiddleware } from './common/middlewares/current-user.middleware';

@Module({
  imports: [
    ConfigModule.forRoot(),
    MongooseModule.forRoot(process.env.DATABASE_URL),
    UsersModule,
    AuthModule,
    CommonModule,
    TelevisionsModule,
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(CurrentUserMiddleware).forRoutes('*');
  }
}

can-modify.guard.ts

import {
  CanActivate,
  ExecutionContext,
  Injectable,
  UnauthorizedException,
} from '@nestjs/common';
import { TelevisionsService } from '../../resources/televisions/televisions.service';
import { UsersService } from '../../resources/users/users.service';

@Injectable()
export class CanModifyGuard implements CanActivate {
  constructor(
    private readonly usersService: UsersService,
    private readonly televisionsService: TelevisionsService,
  ) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    //logics here
  }
}

users.module.ts

import { Module } from '@nestjs/common';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
import { MongooseModule } from '@nestjs/mongoose';
import { User, UserSchema } from './user.entity';
@Module({
  imports: [
    MongooseModule.forFeature([{ name: User.name, schema: UserSchema }]),
  ],
  exports: [UsersService],
  controllers: [UsersController],
  providers: [UsersService],
})
export class UsersModule {}

televisions.module.ts

import { Module } from '@nestjs/common';
import { TelevisionsController } from './televisions.controller';
import { TelevisionsService } from './televisions.service';
import { MongooseModule } from '@nestjs/mongoose';
import { Television, TelevisionSchema } from './television.entity';
import { UsersModule } from '../users/users.module';

@Module({
  imports: [
    MongooseModule.forFeature([
      { name: Television.name, schema: TelevisionSchema },
    ]),
    UsersModule,
  ],
  exports: [TelevisionsService],
  controllers: [TelevisionsController],
  providers: [TelevisionsService],
})
export class TelevisionsModule {}

auth.module.ts

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { UsersModule } from '../users/users.module';
import { ConfigModule } from '@nestjs/config';
import authConfig from './config/auth.config';

@Module({
  imports: [UsersModule, ConfigModule.forFeature(authConfig)],
  controllers: [AuthController],
  providers: [AuthService],
})
export class AuthModule {}

common.module.ts (dont think this file would have any effect but just in case)

import { Module } from '@nestjs/common';
import { APP_GUARD } from '@nestjs/core';
import { AuthorizationRolesGuard } from '../../common/guards/authorization-roles.guard';

@Module({
  providers: [
    {
      provide: APP_GUARD,
      useClass: AuthorizationRolesGuard,
    },
  ],
})
export class CommonModule {}

In order to use the guard, I added the guard to the specific route @UseGuards(CanModifyGuard) and again, it is working fine when I added this guard into television controller but once I added it to user controller the error pops up.

As the error mentioned for potential solutions even though UsersModule is not using any of the TelevisionsService I still imported TelevisionsModule into UsersModule but no luck on getting this fix...and instead I would get another error and said potential cause A circular dependency between modules. Use forwardRef() to avoid it. I read the doc about it and also tried using forwardRef() but still didn't fix it. I might have put the forwardRef() in the wrong place because I am not sure where I should use it.

Thank you in advance for any suggestions or advices.

CodePudding user response:

If I'm understanding your set up correctly, you have a circular dependency on the modules, so you need to forwardRef the imports for those. Using these modules should fix your issue:

user.module.ts

@Module({
  imports: [
    MongooseModule.forFeature([{ name: User.name, schema: UserSchema }]),
    forwardRef(() => TelvisionsModule),
  ],
  exports: [UsersService],
  controllers: [UsersController],
  providers: [UsersService],
})
export class UsersModule {}

televisons.module.ts

@Module({
  imports: [
    MongooseModule.forFeature([
      { name: Television.name, schema: TelevisionSchema },
    ]),
    forwardRef(() => UsersModule),
  ],
  exports: [TelevisionsService],
  controllers: [TelevisionsController],
  providers: [TelevisionsService],
})
export class TelevisionsModule {}
  • Related