for me, I would able to validate nested object with 'class-transformer'
import { Type } from 'class-transformer';
full example:
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;
}
Answer from tarek noaman on Stack Overflowfor me, I would able to validate nested object with 'class-transformer'
import { Type } from 'class-transformer';
full example:
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;
}
You are expecting positions: [1] to throw a 400 but instead it is accepted.
According to this Github issue, this seems to be a bug in class-validator. If you pass in a primitive type (boolean, string, number,...) or an array instead of an object, it will accept the input as valid although it shouldn't.
I don't see any standard workaround besides creating a custom validation decorator:
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);
},
},
});
};
}
and then use it in your dto class:
@ValidateNested({ each: true })
@IsNonPrimitiveArray()
@Type(() => PositionDto)
positions: PositionDto[];
ยป npm install @nestjs/class-validator
ยป npm install class-validator
I just ran into a pretty simple issue, this definition normally should have worked perfectly and pass the validation as price field in JSON is already sent in decimal format as you can figure below, but class-validator keeps raising such error even though I meet the criterias.Whats the best practices to handling this kind of validations on Nestjs, wondering how everyone else would handle that, thanks
create-product.dto.ts
@IsDecimal(
{ force_decimal: true, decimal_digits: '2' },
{ message: 'Price must be a valid number !' },
)
@IsNotEmpty({ message: 'Price is required' })
@Min(0, { message: 'Price must be greater than or equal to 0' })
price: number;request sent
{
// other fields...
"price" : 1574.23,
}response
{
"message": [
"Price must be a valid number !"
],
"error": "Bad Request",
"statusCode": 400
}tried to switch to @IsNumberString type as well but got no luck