I'm trying to validate array of nested objects in nestjs and it works fine. But if I send non-array value like string or null, then I get an error:
TypeError: Cannot read property 'length' of undefined. 
Nested field:
@IsArray()
@ValidateNested({ each: true })
@Type(() => NestedDTO)
nested: NestedDTO[];
How can I validate that value is an array before validate nested objects?
Versions:
NestJS: 6.10.14
class-validator: 0.11.0
                Out-of-the-box support for validation of array of objects is kind of scarce in NestJS so far.
Please have at look at my solution:
The main point is to write and then to use your custom IsArrayOfObjects decorator that will contain the validation logic + @Type decorator from class-transformer module.
import { Type } from 'class-transformer';
import {
  IsString,
  registerDecorator,
  ValidateNested,
  ValidationArguments,
  ValidationOptions,
} from 'class-validator';
export function IsArrayOfObjects(validationOptions?: ValidationOptions) {
  return (object: unknown, propertyName: string) => {
    registerDecorator({
      name: 'IsArrayOfObjects',
      target: object.constructor,
      propertyName,
      constraints: [],
      options: validationOptions,
      validator: {
        validate(value: any): boolean {
          return (
            Array.isArray(value) &&
            value.every(
              (element: any) =>
                element instanceof Object && !(element instanceof Array),
            )
          );
        },
        defaultMessage: (validationArguments?: ValidationArguments): string =>
          `${validationArguments.property} must be an array of objects`,
      },
    });
  };
}
Suppose we have this NestedDTO:
export class NestedDTO {
  @IsString()
  someProperty: string;
}
Then we can simply use it for defining like:
@IsArrayOfObjects()
@ValidateNested()
@Type(() => NestedDTO)
nested: NestedDTO[];
However, this solution will allow empty array to be passed. Then you can add extra condition in IsArrayOfObjects like value.length > 0 and also correct its defaultMessage.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With