class-validator icon indicating copy to clipboard operation
class-validator copied to clipboard

pass run-time context to custom-validator and pass the results to the message

Open roigreenberg opened this issue 4 years ago • 7 comments

Hi I created a custom decorator validator, and I'm facing 2 issues

  1. I need to pass context in run-time (that contains session details). something like validate(myClass, context)
  2. After I validate and found issues, I want to send the details in the message. can I pass a variable between "validate" and "defaultMessage"?

This is what I currently did, but it doesn't work:

type _ValidationOptions = ValidationOptions & {ctx: Context}

export function IsRuleValid(validationOptions?: _ValidationOptions) {
    const _errors: string[] = []
    return function(object: Object, propertyName: string) {
        registerDecorator({
            name: 'IsRuleValid',
            target: object.constructor,
            propertyName: propertyName,
            options: validationOptions,
            validator: {
                validate: async (value: any, args: ValidationArguments) => {
                    const errors = await validate(value, validationOptions?.ctx)
                    _errors.concat(errors)
                    return errors.length === 0
                },
                defaultMessage(args: ValidationArguments): string {
                    return _errors.join()
                },
            },
        })
    }
}

and call it like this:

const errors = await validate(data, {forbidUnknownValues: true, ctx: ctx})

The actual value and args are from the decorator and not from the original call. I need it somehow to pass globally.

roigreenberg avatar Aug 06 '20 12:08 roigreenberg

Is useful when combined with joi or reuse message from the other validation library. If I just throw the Error object from the library, I can't retrieve the ValidationError instance, and can only get the single error rather than the error array.

bangbang93 avatar Sep 01 '20 15:09 bangbang93

I have the same use case. My custom validator uses some internal logic that can return a custom error message. The only way I found to return a dynamic error message from the custom validator is to go through the defaultMessage function.

Therefore, the only solution seems to use a temporary variable like @roigreenberg shows above to store the message, and return that from the defaultMessage function.

belvederef avatar Jun 14 '21 13:06 belvederef

https://github.com/typestack/class-transformer/issues/912

ardyfeb avatar Sep 13 '21 16:09 ardyfeb

1 year, Any update on this ?

ardyfeb avatar Sep 13 '21 16:09 ardyfeb

I have the same use case. My custom validator uses some internal logic that can return a custom error message. The only way I found to return a dynamic error message from the custom validator is to go through the defaultMessage function.

Therefore, the only solution seems to use a temporary variable like @roigreenberg shows above to store the message, and return that from the defaultMessage function.

sadly it's not good, because the error array is created on application boot and not per request and it's shared across all the requests, so because we push in the array it will accumulate on each request, and it can get messy. I couldn't find an option where we instantiate the rule for each request, let's say we do the same request multiple times and the errors array will only grow, it's not per request, it's "global".

t0m4 avatar Jun 16 '22 09:06 t0m4

Any updates on this? Possible work arounds?

miqdadamirali avatar Sep 11 '22 18:09 miqdadamirali