Class-validator - validate array of objects

bensiu picture bensiu · Oct 11, 2019 · Viewed 14.1k times · Source

I am using class-validator package with NestJS and I am looking to validate an array of objects that need to have exactly 2 objects with the same layout:

So far I have:

import { IsString, IsNumber } from 'class-validator';

export class AuthParam {
  @IsNumber()
  id: number;

  @IsString()
  type: string;

  @IsString()
  value: string;
}

and

import { IsArray, ValidateNested } from 'class-validator';
import { AuthParam } from './authParam.model';

export class SignIn {
  @IsArray()
  @ValidateNested({ each: true })
  authParameters: AuthParam[];
}

per @kamilg response (I am able to enforce exacly 2 elements):

import { IsArray, ValidateNested, ArrayMinSize, ArrayMaxSize } from 'class-validator';
import { AuthParam } from './authParam.model';

export class SignInModel {
  @IsArray()
  @ValidateNested({ each: true })
  @ArrayMinSize(2)
  @ArrayMaxSize(2)
  authParameters: AuthParam[];
}

I still can pass an empty array or an array with some other objects not related to AuthParam.

How I should modify it get validation?

Also how I can enforce mandatory 2 elements in the array? MinLength(2) seems to be regarding string... (resolved)

Answer

Yousef khan picture Yousef khan · Oct 13, 2019

Add @Type(() => AuthParam) to your array and it should be working. Type decorator is required for nested objects(arrays). Your code becomes

import { IsArray, ValidateNested, ArrayMinSize, ArrayMaxSize } from 'class-validator';
import { AuthParam } from './authParam.model';
import { Type } from 'class-transformer';

export class SignInModel {
  @IsArray()
  @ValidateNested({ each: true })
  @ArrayMinSize(2)
  @ArrayMaxSize(2)
  @Type(() => AuthParam)
  authParameters: AuthParam[];
}

Be careful if you are using any exception filter to modify the error reponse. Make sure you understand the structure of the class-validator errors.