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

1

10

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?

Catholicism answered 4/8, 2020 at 19:40 Comment(1)
decorators are executed in the reverse order: @A @B target => @A(@B(target)) in your code you clearly using some validation framework, so result order of execution is governed by itSeclusive
B
13

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 you can give 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

Blucher answered 18/5, 2022 at 2:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.