I have problem with ValidationNested and I hope that someone will know how handle with it.
Have you tried to send a request with a string or number in the place where the object should be (which is validated by a @ValidateNested annotation)? It will throw error with status code 500.
Example:
export class ClassA {
@ValidateNested()
@Type(() => ClassB) //annotation from class-transformer
public company: ClassB;
@IsOptional()
@IsInt()
public id?: number;
}
export class ClassB {
@IsInt()
public id: number;
@IsString()
@Length(1, 255) //class-validator will try count length of this string, no matter what :(
public name: string;
}
POST request with body:
{
company: 5,
id: 3
}
response:
{
"type": "http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html",
"title": "Internal Server Error",
"status": 500,
"detail": "TypeError: Cannot read property 'length' of undefined\n ... } //class-validator has tried count ClassB.name length
I'm using class-validator 0.8.5, class-transformer 0.1.9 and routing-controllers 0.7.6
@konradni could you create a PR with a failing test? I see a test that should cover you case and it passes https://github.com/typestack/class-validator/blob/master/test/functional/nested-validation.spec.ts#L105
Hi @konradni!
This seems to be a bug in routing-controllers or class-transformer.
Running this code generates the correct error for me:
import { ValidateNested, IsInt, IsOptional, IsString, Length, validate } from 'class-validator';
export class ClassB {
@IsInt()
public id: number;
@IsString()
@Length(1, 255) //class-validator will try count length of this string, no matter what :(
public name: string;
}
export class ClassA {
@ValidateNested()
// @Type(() => ClassB) //annotation from class-transformer
public company: ClassB;
@IsOptional()
@IsInt()
public id?: number;
}
const a = new ClassA();
a.company = <any>5;
a.id = 3;
validate(a).then(console.log);
It will return with the following (correct) error message in the right place within the error object:
nested property company must be either object or array
Hi there.
Having a similar issue. It appears the validator is not picking up when the type is completely wrong, like where a string is in the place of an object. It will however correctly validate an object with incorrect fields.
I have the following setup:
export class PostInput {
@ValidateNested()
@Type(() => PostInputMessage)
@IsArray()
entries: PostInputMessage[];
}
export class PostInputMessage {
@IsString()
message: string;
}
if my message input contains this:
{
"entries":["Hello", "How are you"]
}
No validation error is thrown. However if my input looks like this:
{
"entries":[{"pinapples":"Hello"}, {"pinapples":"How are you"}]
}
A validation error is correctly thrown.
Versions: class-transformer 0.1.9, class-validator 0.8.1
My mistake, the reason for the error from my first message was the bug in our application.
However, examples below doesn鈥檛 work correctly.
import { ValidateNested, IsInt, validate } from 'class-validator';
class ClassB {
@IsInt()
public id: number;
}
class ClassA {
@ValidateNested()
public company: ClassB;
}
const a = new ClassA();
a.company = <any>[];
validate(a).then(console.log); // returns (no errors): []
const a2 = new ClassA();
a2.company = <any>{};
validate(a2).then(console.log); // returns: []
const a3 = new ClassA();
a3.company = <any>{b: 'c'};
validate(a3).then(console.log); // returns: []
const a4 = new ClassA();
a4.company = <any>[5];
validate(a4).then(console.log); // returns: []
const a5 = new ClassA();
a5.company = <any>['b'];
validate(a5).then(console.log); // returns: []
Apologies for my first comment which was terribly written... please read again, I updated it.
@keenondrums I think that its working when you dont have the @Type decorator. As soon as u put it there, you can happily put a string in place of an object and class-validator wont throw the validation error like it should.
@konradni in your above post, no errors are thrown in each case because you are not specifying the @Type decorator, meaning that the class-validator cannot perform type specific validation on your sub object.
We need @Type to not break the default behaviour of @ValidateNested
@chrisjpalmer The addition of a @Type decorator (from class-transformer) has not changed anything :(. Besides, if I understand correctly, the @Type decorator is not necessary when I create an object using "new ClassName();" (Please correct me if I'm wrong).
@Type decorator is a type hint for reflection system, that has problem with generics like string[] is reflected as Array.
You are right @konandri u shouldn't need the @type decorator IF you are using new keyword. I am confused why class validation does not work at all in the example you provided. I find that it does work for me. I am just having the other issue of generic javascript types not being declared as invalid
@chrisjpalmer
Having a similar issue. It appears the validator is not picking up when the type is completely wrong, like where a string is in the place of an object. It will however correctly validate an object with incorrect fields.
I came across the same problem on Stackoverflow and proposed a custom validator as a workaround.
Most helpful comment
Hi there.
Having a similar issue. It appears the validator is not picking up when the type is completely wrong, like where a string is in the place of an object. It will however correctly validate an object with incorrect fields.
I have the following setup:
if my message input contains this:
No validation error is thrown. However if my input looks like this:
A validation error is correctly thrown.
Versions: class-transformer 0.1.9, class-validator 0.8.1