I want to validate a field in Dto to check that if it exists in database, for that I am creating a custom decorator.
Here's my Dto
export default class MyDto {
@IsNotEmpty({ message: 'Email is required' })
@IsEmail({}, { message: 'Email must be a valid email' })
@Exists<Users>('id', { message: 'Email is invalid' })
email: string;
}
Here's my custom decorator code
export function Exists<T extends Object>(columnName: keyof T, validationOptions?: ValidationOptions) {
return function (object: Object, propertyName: string) {
registerDecorator({
target: object.constructor,
propertyName: propertyName,
constraints: [columnName],
options: validationOptions,
validator: ExistsValidation<T>
});
};
}
and Here's my validation code
@ValidatorConstraint({ name: 'Exists', async: true })
@Injectable()
export class ExistsValidation<T extends Object> implements ValidatorConstraintInterface {
constructor(
@InjectRepository(T)
private readonly repository: Repository<T>
) { }
async validate(value: any, args: ValidationArguments): Promise<boolean> {
const [columnName] = args.constraints;
return await this.repository.findOne(
{ where: { [columnName]: value } }
) ? true : false;
}
}
But the issue is @InjectRepository does not take type instead it takes EntityClassOrSchema but I can't understand how to pass it in there.
Working on this problem for two days any help would be appreciated.
Finally found the solution instead of injecting Repository I injected the dataSource
constructor(
private readonly connection: DataSource
) { }
Like this and then use it to create QueryRunner and use it for query like this
const queryRunner = this.connection.createQueryRunner();
const result = await queryRunner.query(query);