Saltar al contenido

Validar objetos anidados usando el validador de clases y nestjs

Solución:

Estas esperando positions: [1] lanzar un 400 pero en cambio se acepta.

De acuerdo con este problema de Github, esto parece ser un error en el validador de clases. Si pasa un tipo primitivo (boolean, string, number, …) o un array en lugar de un objeto, aceptará la entrada como válida aunque no debería.


No veo ninguna solución alternativa estándar además de crear un decorador de validación personalizado:

import { registerDecorator, ValidationOptions, ValidationArguments } from 'class-validator';

export function IsNonPrimitiveArray(validationOptions?: ValidationOptions) {
  return (object: any, propertyName: string) => {
    registerDecorator({
      name: 'IsNonPrimitiveArray',
      target: object.constructor,
      propertyName,
      constraints: [],
      options: validationOptions,
      validator: {
        validate(value: any, args: ValidationArguments) {
          return Array.isArray(value) && value.reduce((a, b) => a && typeof b === 'object' && !Array.isArray(b), true);
        },
      },
    });
  };
}

y luego úselo en su clase dto:

@ValidateNested({ each: true })
@IsNonPrimitiveArray()
@Type(() => PositionDto)
positions: PositionDto[];

para mí, podría validar el objeto anidado con 'class-transformer'

import { Type } from 'class-transformer';

ejemplo completo:

import {
  MinLength,
  MaxLength,
  IsNotEmpty,
  ValidateNested,
  IsDefined,
  IsNotEmptyObject,
  IsObject,
  IsString,
} from 'class-validator';
import { Type } from 'class-transformer';

class MultiLanguageDTO {
  @IsString()
  @IsNotEmpty()
  @MinLength(4)
  @MaxLength(40)
  en: string;

  @IsString()
  @IsNotEmpty()
  @MinLength(4)
  @MaxLength(40)
  ar: string;
}

export class VideoDTO {
  @IsDefined()
  @IsNotEmptyObject()
  @IsObject()
  @ValidateNested()
  @Type(() => MultiLanguageDTO)
  name!: MultiLanguageDTO;
}
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *