Home > Net >  How to pass class-validator @isArray when single item comes from query param
How to pass class-validator @isArray when single item comes from query param

Time:07-10

I'm trying to validate request with class-validator if it's array.

inputs comes from query param with /api/items?someTypes=this

my request dto looks like this.

    (...)
    @IsArray()
    @IsEnum(SOMETHING, {each: true})
    readonly someTypes: keyof typeof SOMETHING[];
    (...)

when I give only one item, @IsArray gives validation error, saying it is not an array.

I want to make it array too when one item comes from query param, but I don't know how.

I know using /api/items?someTypes[]=this will pass validation.

but I want to know if there is another way to solve this.

CodePudding user response:

If your field is an array and you want to perform validation of each item in the array you must pass a special each: true option to the @IsEnum() decorator.

import { IsArray, IsEnum } from 'class-validator';

enum SomeType {
  A,
  B,
  C,
}

class SearchQuery {
  @IsArray()
  @IsEnum(SomeType, { each: true })
  types: SomeType[];
}


@Controller()
export class AppController {
  @Get()
  async search(@Query() searchQuery: SearchQuery): Promise<void> 
  { ... }
}

You can then perform a GET request to your endpoint using the following syntax.

?types[]=A&types[]=B&types[]=C

That works perfectly fine when you pass just one item.

?types[]=A

If you don't like this syntax and prefer types=A,B,C then you can combine class-validator with class-tranformer.

class SearchQuery {
  @IsArray()
  @IsEnum(SomeType, { each: true })
  @Transform(({ value }) =>
    value
      .trim()
      .split(',')
      .map((type) => SomeType[type]),
  )
  types: SomeType[];
}

CodePudding user response:

You already set the each option, so you don't need to use @IsArray. validating-arrays

  • Related