Skip to content

Unable to use cutom validator, since it is saying it is not a function #2457

Open
@NicolasGorga

Description

@NicolasGorga

Hello, I defined a custom validator, as many others i have working correctly, but i am getting an error:

(0, is_valid_order_generation_flow_1.IsValidOrderGenerationFlow)(),
^
TypeError: (0 , is_valid_order_generation_flow_1.IsValidOrderGenerationFlow) is not a function
at Object. (E:\proyectos personales\centr0\backend\universal-clothing-api\node_modules\universal-clothing-shared\dist\order\CreateOrderRequestDTO.js:27:69)
at Module._compile (node:internal/modules/cjs/loader:1376:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1435:10)
at Object.require.extensions. [as .js] (E:\proyectos personales\centr0\backend\universal-clothing-api\node_modules\ts-node\src\index.ts:1608:43)
at Module.load (node:internal/modules/cjs/loader:1207:32)
at Function.Module._load (node:internal/modules/cjs/loader:1023:12)
at Module.require (node:internal/modules/cjs/loader:1235:19)
at require (node:internal/modules/helpers:176:18)
at Object. (E:\proyectos personales\centr0\backend\universal-clothing-api\node_modules\universal-clothing-shared\dist\order\index.js:18:14)
at Module._compile (node:internal/modules/cjs/loader:1376:14)

I am using the validator in my express api, which imports it from an npm package i published where i expose types and validators to share between my frontend and backend. Here is how the validator looks in the shared types library:

`import { ValidationArguments, ValidationOptions, ValidatorConstraint, ValidatorConstraintInterface, registerDecorator } from "class-validator";
import { allowedOrderGenerationFlows } from "../../order";

@ValidatorConstraint({ name: 'isValidOrderGenerationFlow', async: false })
class IsValidOrderGenerationFlowConstraint implements ValidatorConstraintInterface {
validate(value: any, args?: ValidationArguments | undefined) {
return allowedOrderGenerationFlows.includes(value);
}

defaultMessage?(validationArguments?: ValidationArguments | undefined): string {
    return  `Flow de generacion de orden: ${validationArguments?.value} es invalido. Valores posibles son ${allowedOrderGenerationFlows.join(', ')}`;
}

}

export function IsValidOrderGenerationFlow(validationOptions?: ValidationOptions) {
return function(object: Object, propertyName: string) {
registerDecorator({
target: object.constructor,
propertyName,
constraints: [],
options: validationOptions,
validator: IsValidOrderGenerationFlowConstraint,
});
}
}`

Here is the DTO in the shared library that uses it:

`import { ArrayNotEmpty, IsEmail, IsOptional, IsString } from "class-validator";
import { OrderGenerationFlow } from ".";
import { IsValidOrderGenerationFlow } from "../typeorm/custom-validators/is-valid-order-generation-flow";

export class CreateOrderRequestDTO {
@ArrayNotEmpty({ message: 'No puede ser un array vacio' })
@IsString({ message: 'Cada elemento debe ser un string', each: true })
items!: string[];

@IsValidOrderGenerationFlow()
orderGenerationFlow!: OrderGenerationFlow;

@IsOptional()
@IsEmail(undefined, { message: "Debe ser un email valido" })
clientEmail?: string;

}`

And here is how i am using it in my backend, just like all other DTOs i use which don't fail, even those using a custom validator:

const requestDTO = await validateRequestBody(OrderDTO.CreateOrderRequestDTO, req.body);

I have another custom validator which doesn't fail which is almost identical to this one, in terms of the validation it performs and the usage inside a DTO. This doesn't fail:

`import { ValidationArguments, ValidationOptions, ValidatorConstraint, ValidatorConstraintInterface, registerDecorator } from "class-validator";
import { allowedProductConditions } from "../../product";

@ValidatorConstraint({ name: 'isValidProductCondition', async: false })
class IsValidProductConditionConstraint implements ValidatorConstraintInterface {
validate(condition: any, args: ValidationArguments) {
return allowedProductConditions.includes(condition);
}

defaultMessage?(validationArguments?: ValidationArguments | undefined): string {
    return  `Invalid product condition. Allowed product conditions: ${allowedProductConditions.join(', ')}`;
}

}

export function IsValidProductCondition(validationOptions?: ValidationOptions) {
return function (object: Object, propertyName: string) {
registerDecorator({
target: object.constructor,
propertyName,
options: validationOptions,
constraints: [],
validator: IsValidProductConditionConstraint,
});
}
}`

DTO usage:

`
import { Type } from 'class-transformer';
import { ArrayNotEmpty, IsArray, IsBoolean, IsNotEmptyObject, IsNumber, IsOptional, IsPositive, IsString, MinLength, ValidateNested } from 'class-validator';
import { AssignSizeToProductDTO, BaseProductConditionDTO, ProductCondition, ProductSizeDTO } from '.';
import { BaseStoreDTO } from '../store';
import { IsValidProductCondition } from '../typeorm/custom-validators/is-valid-product-condition';
import { ProductBaseCategoryDTO } from './ProductCategory';

export class CreateProductDTO {
@IsString()
title!: string;

@IsPositive() 
price!: number;

@IsValidProductCondition()
condition!: ProductCondition;

@IsNotEmptyObject(undefined, { message: '\'size\' tiene que ser un objeto' })
@ValidateNested()
@Type(() => AssignSizeToProductDTO)
size!: AssignSizeToProductDTO

@IsNumber()
categoryId!: number;

@IsOptional()
@IsString()
description?: string;

@IsOptional()
@IsString()
brand?: string;

@IsOptional()
@IsString()
color?: string;

}`

Please this is driving me nuts, any help is appreciated!

Metadata

Metadata

Assignees

No one assigned

    Labels

    type: questionQuestions about the usage of the library.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions