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

question: How to use IsOptional with groups?

Open boy51 opened this issue 3 years ago • 3 comments

I was trying to...

In a nestjs app, I recieve a DTO as part of a POST request. This DTO is used to create an entity in the DB. But some values are not set in the frontend, and rather calculated in the backend.

So basically, when the request comes in some values are not set but later on they are required.

I thought that groups would be a great solution for this but the IsOptional decorator doesn't behave in the way I thought it would. See below code

The problem: So my dto looks something like this

class DTO {
   @IsString()
   uid!: string

   @IsOptional({ groups: ['request'] })
   @IsString()
   @Length(3, 100)
   outlinePath?: string
}

I tested it, expecting that validation with group 'request' will work, but validation without group will fail, as outlinePath should be optional only for the 'request' group.

    const Yo = new DTO()
    Yo.uid = 'OO00'

    const errors = await validate(Yo)
    const errorsWGroup = await validate(Yo, { groups: ['request'] })
    console.log('Validate with group request: ', errorsWGroup.length === 0)
    console.log('Validate without group: ', errors.length === 0)

But both validations are successful.

Validate with group request:  true
Validate without group:  true

So how can I do this? Is there a better solution?

boy51 avatar Sep 09 '20 18:09 boy51

@boy51 read about always: true

ruscon avatar Sep 16 '20 18:09 ruscon

Hi! I have exact the same issue, @IsOptional decorator ignores validation groups passed in and works without any dependency on groups.

always: true flag isn't the case, because I need to @IsOptional work only in some of the validation groups, not in all of them.

volodymyr-sevastianov avatar Nov 18 '21 12:11 volodymyr-sevastianov

I believe if you use groups for one of the decorators, you'll need to add the groups to the rest of the decorators. As such:

class DTO {
   @IsString()
   uid!: string

   @IsOptional({ groups: ['request'] })
   @IsString({ groups: ['other-groups'] })
   @Length(3, 100, { groups: ['other-group'] })
   outlinePath?: string
}

Alternatively if you do not want to do this, you can use @IsNotEmpty instead. But that's a reverse.

class DTO {
   @IsString()
   uid!: string

   @IsNotEmpty({ groups: ['other-groups'] })
   @IsString()
   @Length(3, 100)
   outlinePath?: string
}

keithtxw avatar Apr 26 '22 09:04 keithtxw

This doesn't make any sense and IMO is a bug in class-validator. Why should IsOptional ignore groups? It should take them into account and only apply if the proper groups are used.

raress96 avatar Mar 09 '23 15:03 raress96