ackuser
ackuser

Reputation: 5899

Nestjs custom class-validator decorator doesn't get the value from param

I have created a Custom ValidatorConstraint in Nestjs from class-validator, just to create my own decorator and apply later to DTO classes for validations.

Imagine this route.

foo/:client

after request it, I just want to check that client contains some pattern

client --> XXX123 ✘

client --> ZZZ123 ✔

I am struggling with it and although I saw some examples, it is still not very clear why it fails.

main.ts

app.useGlobalPipes(new ValidationPipe());
useContainer(app.select(AppModule), { fallbackOnErrors: true });

app.module.ts

providers: [..., IsValidClientConstraint],

app.controller.ts

  @Get(':client')
  getHello(@Param('client') client: ClientDTO): string {

custom.validator.ts

import { registerDecorator, ValidationArguments, ValidationOptions, ValidatorConstraint, ValidatorConstraintInterface } from 'class-validator';
import { Injectable } from '@nestjs/common';

@ValidatorConstraint({ async: false })
@Injectable()
export class IsValidClientConstraint implements ValidatorConstraintInterface {
  validate(client: any, args: ValidationArguments) {
    console.log(client)
    return client.includes('ZZZ');
  }
}

export function IsValidClient(validationOptions?: ValidationOptions) {
  return function (object: Object, propertyName: string) {
    registerDecorator({
      target: object.constructor,
      propertyName: propertyName,
      options: validationOptions,
      constraints: [],
      validator: IsValidClientConstraint,
    });
  };
}

client.dto.ts

export class ClientDTO {


  @IsValidClient({ message: 'blabla' })
  client: string;

}

However doing a request with -> foo/XXX344

ERROR [ExceptionsHandler] Cannot read properties of undefined

So it is not receiving the value of the client itself

What am I missing there?

I with leave the repo here

https://github.com/ackuser/nestjs-sample-custom-validator

Thanks,

I appreciate any help

Upvotes: 1

Views: 5119

Answers (1)

omidh
omidh

Reputation: 2832

You don't have to pass parameter name to @Param decorator when you want to use class-validator to validate params, So change it to @Param() params: ClientDTO instead.

Use custom pipes if you want to validate each parameter one by one. because the DTO method you used turns all parameters (not just :client) into a single data class.

Also in IsValidClientConstraint check if client is defined before using it.

Upvotes: 1

Related Questions