Class-validator: feat: IsOptional allow empty strings

Created on 7 Mar 2019  路  5Comments  路  Source: typestack/class-validator

I would like to extend the decorator "IsOptional" for my validation. I would like empty strings like "" to be valid as well. I started with this, but this seems to be the wrong approach:

export function IsOptionalWithEmptyString(validationOptions?: ValidationOptions) {
    return function (object: Object, propertyName: string) {
        registerDecorator({            
            name: "isOptionalWithEmptyString",
            target: object.constructor,
            propertyName: propertyName,
            constraints: [function (object, value) {
                return object[propertyName] !== null && object[propertyName] !== undefined && object[propertyName] !== "";
            }],
            options: validationOptions,
            validator: ?
        });
    };
}

How could I implement this? Thank you for your work.

needs discussion feature

Most helpful comment

I have found a solution for this, you can create a new decorator wrapping ValidateIf like as follows.

import { ValidationOptions, ValidateIf } from 'class-validator';

export function IsOptional(validationOptions?: ValidationOptions) {
  return ValidateIf((obj, value) => {
    return value !== null && value !== undefined && value !== '';
  }, validationOptions);
}

All 5 comments

Duplicate of #232?

Thanks for your answer :smiley: , but I don't think this is a duplicate, because #232 is more about a discussion about whether "IsOptional" should also allow empty strings. I think it's ok that "IsOptional" doesn't implement empty strings, but I'd like to implement "IsOptionalWithEmptyString". Or more generally, how can I develop a decorator that disables the following decorators due to a condition?

Any update ?

None of the code bellow is working, I need to allow an empty string or an url:

  @IsDefined()
  @ValidateIf(e => e !== '') // expected to allow empty string by skipping @IsUrl
  @IsUrl()
  readonly externalLink: string = '';

  @IsDefined()
  @ValidateIf(e => e === '') // allow everything ?
  @IsUrl()
  readonly externalLink: string = '';

https://github.com/typestack/class-validator#conditional-validation

externalLink === '' should be valid
externalLink === null should be invalid
externalLink === undefined should be invalid
externalLink === 'https://github.com/typestack/class-validator/issues/326' should be valid

I have found a solution for this, you can create a new decorator wrapping ValidateIf like as follows.

import { ValidationOptions, ValidateIf } from 'class-validator';

export function IsOptional(validationOptions?: ValidationOptions) {
  return ValidateIf((obj, value) => {
    return value !== null && value !== undefined && value !== '';
  }, validationOptions);
}

@ambroiseRabier try this out

  @IsUrl()
  @ValidateIf(e => e.externalLink !== '') // check only when blank string not found
  readonly externalLink: string = '';

Because in @ValidateIf first parameter is an object containing the all property of current class not the property it self.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

otbe picture otbe  路  5Comments

linck5 picture linck5  路  6Comments

MistyKuu picture MistyKuu  路  3Comments

jerradpatch picture jerradpatch  路  5Comments

st-clair-clarke picture st-clair-clarke  路  3Comments