Home > other >  Two validators for one single entity in DTO
Two validators for one single entity in DTO

Time:01-25

Are there any ways or would it be possible to have two validator in one single entity? Like for the given example code below, the identifier would accept an email as its payload but it would also accept number/mobile number as its payload as well.

  @ApiProperty()
  @IsString()
  @IsNotEmpty()
  @IsEmail()
  identifier: string;

EDIT:

I have tried,

  @ApiProperty()
  @IsString()
  @IsNotEmpty()
  @IsEmail()
  @IsPhoneNumber('US')
  identifier: string;

But it does not work.

EDIT 2: I found a reference code based on this previous thread, How to use else condition in validationif decorator nestjs class-validator?, and I copied his validation class.

import { ValidatorConstraint, ValidatorConstraintInterface, ValidationArguments } from "class-validator";
import { IdentifierType } from "../interface/access.interface";

@ValidatorConstraint({ name: 'IdentifierValidation', async: false })
export class IdentifierValidation implements ValidatorConstraintInterface {
    validate(identifier: string, args: ValidationArguments) {

        if (JSON.parse(JSON.stringify(args.object)).type === IdentifierType.MOBILE) {

            var regexp = new RegExp('/^[\ ]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$/im');
            // "regexp" variable now validate phone number.
            return regexp.test(identifier);
        } else {
            regexp = new RegExp("^[a-zA-Z0-9_. -] @[a-zA-Z0-9-] \.[a-zA-Z0-9-.] $");
            // "regexp" variable now validate email address.
            return regexp.test(identifier);
        }

    }

    defaultMessage(args: ValidationArguments) {

        if (JSON.parse(JSON.stringify(args.object)).type === IdentifierType.MOBILE) {
            return 'Enter a valid phone number.'
        } else {
            return 'Enter a valid email address.'
        }
    }
}

DTO -

export class VerifyOtpDto {
  @Validate(IdentifierValidation)
  @ApiProperty()
  @IsNotEmpty()
  identifier: string;

  @ApiProperty({ enum: IdentifierType })
  @IsNotEmpty()
  identifierType: IdentifierType;
}

ENUM -

export enum IdentifierType {
  EMAIL = 'email',
  MOBILE = 'mobile',
}

It does work with email but trying to feed a mobile number still does not work.

CodePudding user response:

You have two ways to do this, first with regex:

@Matches(/YOUR_REGEX/, {message: 'identifier should be email or phone'})
identifier: string;

Or you can get the idea from this:

@IsType(Array<(val: any) => boolean>)
@IsType([
 val => typeof val == 'string',
 val => typeof val == 'boolean',
])
private readonly foo: boolean | string;

CodePudding user response:

Of course it can get more than one validator in one DTO column.

Did you check https://www.npmjs.com/package/class-validator here?

if you want to check mobile number, you can use to @IsMobilePhone(locale: string).

  •  Tags:  
  • Related