If you are experiencing this issue, here is a solution:
To use dependencies in your custom validator constraint classes with class-validator, you need to implement service containers. More information can be found at: https://github.com/typestack/class-validator#using-service-container
import {useContainer, Validator} from "class-validator";
// Add this code at the global application level:
useContainer(Container);
Make sure to include the use container function at the global application level.
1. Insert the following code into your main.ts bootstrap function after declaring the app:
async function bootstrap() {
const app = await NestFactory.create(AppModule);
useContainer(app.select(AppModule), { fallbackOnErrors: true });
...}
The {fallbackOnErrors: true} parameter is necessary as Nest will throw an Exception if the required class is not available in DI.
2. Apply Injectable() to your constraint:
import {ValidatorConstraint, ValidatorConstraintInterface} from 'class-validator';
import {UsersService} from './user.service';
import {Injectable} from '@nestjs/common';
@ValidatorConstraint({ name: 'isUserAlreadyExist', async: true })
@Injectable() // Required for injecting the class into the module
export class IsUserAlreadyExist implements ValidatorConstraintInterface {
constructor(protected readonly usersService: UsersService) {}
async validate(text: string) {
const user = await this.usersService.findOne({
email: text
});
return !user;
}
}
3. Inject the constraint as a provider into your module and ensure that the service you plan to inject into the constraint is also accessible at a module level:
import {Module} from '@nestjs/common';
import { UsersController } from './user.controller';
import { UsersService } from './user.service';
import { IsUserAlreadyExist } from './user.validator';
@Module({
controllers: [UsersController],
providers: [IsUserAlreadyExist, UsersService],
imports: [],
exports: []
})
export class UserModule {
}