Last active
May 16, 2024 18:36
-
-
Save 413x1/e76dad29e37503df9ec0b0184fe7611b to your computer and use it in GitHub Desktop.
nest_custom_validation.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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'; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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, | |
}) | |
} | |
} |
users.dto.ts
@isUnique({tableName: 'users', column: 'username'})
// the above line is causing EntityMetadataNotFoundError: No metadata for "users" was found
any idea why is it being caused
here's my github code: https://github.com/abhishek1141781/boundcode
@isUnique({tableName: 'users', column: 'username'})
that line is a decorator function with table name and field name as parameter so you should adjust it with your database tabel and field to validating your data
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
users.dto.ts
@isUnique({tableName: 'users', column: 'username'})
// the above line is causing EntityMetadataNotFoundError: No metadata for "users" was found
any idea why is it being caused
here's my github code: https://github.com/abhishek1141781/boundcode