Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I specify the order to execute validation decorators with class-validator?

Let's say one has a class, Post, that one wants to validate.

export class Post {
  @IsArray()
  tags: string[];
}

Let's now say that he wants to ensure that the word 'mistake' never appears in the tags field. He writes a custom validation decorator to do this:

export function NoMistakes (validationOptions?: ValidationOptions) {
  return function (object: Object, propertyName: string) {
    registerDecorator({
      name: 'noMistakes',
      target: object.constructor,
      propertyName: propertyName,
      options: validationOptions,
      validator: {
        validate (tags: any, args: ValidationArguments) {
          tags.forEach(tag => {
            if (tag == 'mistake') {
              return false;
            }
          });

          return true;
        }
      }
    });
  }
}

Now, he rewrites Post as so:

export class Post {
  @IsArray()
  @NoMistakes()
  tags: string[];
}

The problem occurs, for example, when tags in not of type int. In this case, an error occurs in the custom validator when trying to iterate over something that is not an array.

How can one have the validator @IsArray be executed before the custom validator? In general, is there a way one can choose the order of the validations?

like image 836
yalpsid eman Avatar asked Nov 15 '22 07:11

yalpsid eman


1 Answers

Typescript decorator order follows: see

  1. The expressions for each decorator are evaluated top-to-bottom.
  2. The results are then called as functions from bottom-to-top.

That means class-validator checks validation decorator bottom-to-top
So, you can edit your Post class like this.

export class Post {
  @NoMistakes() // 2nd
  @IsArray() // 1st
  tags: string[];
}

And giving stopAtFirstError options to skip @NoMistakes() when @IsArray makes an error.
get more informations about validator options:
https://www.npmjs.com/package/class-validator#passing-options

like image 161
leafy Avatar answered Feb 18 '23 23:02

leafy