0

When trying to import another module inside of my dynamic modules nest throws the following error when using a service exported by that module inside of my services:

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

When importing the Module with static configuration inside the @Module decorator everything works fine.

/** UsersModule */
@Global()
@Module({
  imports: [
    MikroOrmModule.forFeature([UserEntity]),
    JwtModule.register({
      secret: 'secret',
    }),
  ],
  providers: [UsersService, ActivationService, PasswordResetService],
  exports: [UsersService],
  controllers: [
    MyUserController,
    UsersController,
    ActivationController,
    PasswordResetController,
  ],
})
export class UsersModule {
  /**
   * Creates UsersModule asynchronously
   * @param options
   */
  public static forRootAsync(
    options: AsyncModuleOptions<UsersModuleOptions>,
  ): DynamicModule {
    return {
      module: UsersModule,
      imports: [...(options.imports || [])],
      providers: createAsyncModuleOptionsProviders(
        options,
        USERS_MODULE_OPTIONS,
      ),
      exports: [USERS_MODULE_OPTIONS],
    };
  }
}

By importing the JwtModule inside of the forRootAsync method of my dynamic module im getting the error above.

/** UsersModule */
@Global()
@Module({
  imports: [MikroOrmModule.forFeature([UserEntity])],
  providers: [UsersService, ActivationService, PasswordResetService],
  exports: [UsersService],
  controllers: [
    MyUserController,
    UsersController,
    ActivationController,
    PasswordResetController,
  ],
})
export class UsersModule {
  /**
   * Creates UsersModule asynchronously
   * @param options
   */
  public static forRootAsync(
    options: AsyncModuleOptions<UsersModuleOptions>,
  ): DynamicModule {
    return {
      module: UsersModule,
      imports: [
        JwtModule.registerAsync({
          inject: [USERS_MODULE_OPTIONS],
          useFactory: async (options: UsersModuleOptions) => ({
            secret: options.secret,
            privateKey: options.privateKey,
            publicKey: options.publicKey,
          }),
        }),
        ...(options.imports || []),
      ],
      providers: createAsyncModuleOptionsProviders(
        options,
        USERS_MODULE_OPTIONS,
      ),
      exports: [USERS_MODULE_OPTIONS],
    };
  }
}

I have already used this kind of configuration successfully in another module without obtaining the error:

/** JwtAuthenticationModule */
@Global()
@Module({
  imports: [PassportModule],
  providers: [
    JwtAuthenticationService,
    JwtStrategy,
    {
      provide: APP_GUARD,
      useClass: JwtAuthenticationGuard,
    },
  ],
  exports: [JwtAuthenticationService],
  controllers: [JwtAuthenticationController],
})
export class JwtAuthenticationModule {
  /**
   * Creates JwtAuthenticationModule asynchronously
   * @param options
   */
  public static forRootAsync(
    options: AsyncModuleOptions<JwtAuthenticationModuleOptions>,
  ): DynamicModule {
    return {
      module: JwtAuthenticationModule,
      imports: [
        JwtModule.registerAsync({
          inject: [JWT_AUTHENTICATION_MODULE_OPTIONS],
          useFactory: async (options: JwtAuthenticationModuleOptions) => ({
            secret: options.secret,
            privateKey: options.privateKey,
            publicKey: options.publicKey,
          }),
        }),
        ...(options.imports || []),
      ],
      providers: [
        this.getUsersServiceProvider(),
        ...createAsyncModuleOptionsProviders(
          options,
          JWT_AUTHENTICATION_MODULE_OPTIONS,
        ),
      ],
      exports: [JWT_AUTHENTICATION_MODULE_OPTIONS],
    };
  }

  /**
   * Fetches UsersServiceProvider from options
   * @private
   */
  private static getUsersServiceProvider(): Provider<UsersServiceContract> {
    return {
      inject: [JWT_AUTHENTICATION_MODULE_OPTIONS],
      provide: USERS_SERVICE,
      useFactory: (options: JwtAuthenticationModuleOptions) =>
        options.usersService,
    };
  }
}

Importing the JwtModule with a static secret inside of the forRootAsync method also throws the same error.


/** UsersModule */
@Global()
@Module({
  imports: [MikroOrmModule.forFeature([UserEntity])],
  providers: [UsersService, ActivationService, PasswordResetService],
  exports: [UsersService],
  controllers: [
    MyUserController,
    UsersController,
    ActivationController,
    PasswordResetController,
  ],
})
export class UsersModule {
  /**
   * Creates UsersModule asynchronously
   * @param options
   */
  public static forRootAsync(
    options: AsyncModuleOptions<UsersModuleOptions>,
  ): DynamicModule {
    return {
      module: UsersModule,
      imports: [
        JwtModule.register({
          secret: 'secret',
        }),
        ...(options.imports || []),
      ],
      providers: createAsyncModuleOptionsProviders(
        options,
        USERS_MODULE_OPTIONS,
      ),
      exports: [USERS_MODULE_OPTIONS],
    };
  }
}

1 Answers1

0

Try to import the AuthModule on the UsersModule

ardritkrasniqi
  • 739
  • 5
  • 13
  • The AuthModule and UsersModule are independent from each other in order to make them exchangeable easily. Importing the JwtAuthenticationModule inside of the UsersModule also requires the JwtAuthenticationModule to be configured with its dynamic module options as well. I tried importing it but that didn't change a thing. – dennis-neuhaus Apr 29 '22 at 09:08