fmagno
fmagno

Reputation: 1548

javascript/typescript | class-validator | custom validation decorators | override the `validationOptions` inside the `validator` method

Consider the example provided in section Custom validation decorators:

// Decorator definition


import { registerDecorator, ValidationOptions, ValidationArguments } from 'class-validator';

export function IsLongerThan(property: string, validationOptions?: ValidationOptions) {
  return function (object: Object, propertyName: string) {
    registerDecorator({
      name: 'isLongerThan',
      target: object.constructor,
      propertyName: propertyName,
      constraints: [property],
      options: validationOptions,
      validator: {
        validate(value: any, args: ValidationArguments) {
          const [relatedPropertyName] = args.constraints;
          const relatedValue = (args.object as any)[relatedPropertyName];
          return typeof value === 'string' && typeof relatedValue === 'string' && value.length > relatedValue.length; // you can return a Promise<boolean> here as well, if you want to make async validation
        },
      },
    });
  };
}
// Decorator usage


import { IsLongerThan } from './IsLongerThan';

export class Post {
  title: string;

  @IsLongerThan('title', {
    /* you can also use additional validation options, like "groups" in your custom validation decorators. "each" is not supported */
    message: 'Text must be longer than the title',
  })
  text: string;
}

How can I set/override the message string conditionally, inside the validator method? Is this possible?

Upvotes: 5

Views: 3927

Answers (1)

fmagno
fmagno

Reputation: 1548

Found it:



export function IsLongerThan(property: string, validationOptions?: ValidationOptions) {
  return function (object: Object, propertyName: string) {

    let message;

    const validate = function (value: any, args: ValidationArguments) {
      // Set message based on some validation logic
      // message = ...
    }

    const defaultMessage = function () {
      return message;
    }

    registerDecorator({
      name: 'isLongerThan',
      target: object.constructor,
      propertyName: propertyName,
      constraints: [property],
      options: validationOptions,
      validator: {
        validate,
        defaultMessage
      },
    });
  };
}

Upvotes: 2

Related Questions