Skip to content

Instantly share code, notes, and snippets.

@413x1
Last active May 16, 2024 18:36
Show Gist options
  • Save 413x1/e76dad29e37503df9ec0b0184fe7611b to your computer and use it in GitHub Desktop.
Save 413x1/e76dad29e37503df9ec0b0184fe7611b to your computer and use it in GitHub Desktop.
nest_custom_validation.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UsersModule } from './users/users.module';
import { TypeOrmModule } from '@nestjs/typeorm';
import { typeOrmConfig } from './configs/db';
import { IsUniqueConstraint } from './utils/validators';
@Module({
imports: [
TypeOrmModule.forRoot(typeOrmConfig),
UsersModule
],
controllers: [AppController],
providers: [
AppService, IsUniqueConstraint],
})
export class AppModule {}
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ValidationPipe } from '@nestjs/common';
import { useContainer } from 'class-validator';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// app use global to automaticly validate requests
app.useGlobalPipes(new ValidationPipe());
// wrap AppModule with UseContainer
useContainer(app.select(AppModule), {fallbackOnErrors: true});
await app.listen(3000);
}
bootstrap();
import { IsEmail, IsNotEmpty, MinLength, Validate } from "class-validator";
import { isUnique } from "src/utils/validators";
export class UserCreateDto {
@IsNotEmpty()
@isUnique({tableName: 'users', column: 'username'})
username: string;
@IsNotEmpty()
@IsEmail()
@isUnique({tableName: 'users', column: 'email'})
email: string;
@IsNotEmpty()
@MinLength(3)
password: 'string';
@IsNotEmpty()
first_name: 'string';
@IsNotEmpty()
last_name: 'string';
}
import { BaseCustomEntity } from "src/utils/entity";
import { Column, Entity } from "typeorm"
@Entity('users')
export class User extends BaseCustomEntity {
@Column()
username: string;
@Column({
unique: true
})
email: string;
@Column()
first_name: string;
@Column()
password: string;
@Column()
last_name: string;
@Column({ default: true })
is_active: boolean;
}
import { Injectable } from "@nestjs/common";
import { ValidationArguments, ValidationOptions, ValidatorConstraint, ValidatorConstraintInterface, registerDecorator } from "class-validator";
import { EntityManager } from "typeorm";
// decorator options interface
export type IsUniqeInterface = {
tableName: string,
column: string
}
@ValidatorConstraint({name: 'IsUniqueConstraint', async: true})
@Injectable()
export class IsUniqueConstraint implements ValidatorConstraintInterface {
constructor(private readonly entityManager: EntityManager) {}
async validate(
value: any,
args?: ValidationArguments
): Promise<boolean> {
// catch options from decorator
const {tableName, column}: IsUniqeInterface = args.constraints[0]
// database query check data is exists
const dataExist = await this.entityManager.getRepository(tableName)
.createQueryBuilder(tableName)
.where({[column]: value})
.getExists()
return !dataExist
}
defaultMessage(validationArguments?: ValidationArguments): string {
// return custom field message
const field: string = validationArguments.property
return `${field} is already exist`
}
}
// decorator function
export function isUnique(options: IsUniqeInterface, validationOptions?: ValidationOptions) {
return function (object: any, propertyName: string) {
registerDecorator({
name: 'isUnique',
target: object.constructor,
propertyName: propertyName,
options: validationOptions,
constraints: [options],
validator: IsUniqueConstraint,
})
}
}
@abhishek1141781
Copy link

This is now resolved, thanks @413x1 . In the database the name of the table is 'user' and not 'users'. Silly mistake really. Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment