joiful-ts / joiful

TypeScript Declarative Validation for Joi
239 stars 18 forks source link

Nested objects not validating #226

Closed randy-halim closed 2 years ago

randy-halim commented 2 years ago

I have two classes, one referencing another:

class Address {
  @(jf.string().required().label("Address Line 1").min(1))
  line1!: string;

  @(jf.string().label("Address Line 2"))
  line2?: string;

  // so on...
}
class RegisterDetails {
  // ...

  @(jf.object.required())
  address_shipping!: Address;
}

When I validate with RegisterDetails, all the normal validators (strings, numbers, etc.) work as expected; the nested object is not. Does anyone have any ideas on what's going on? Thanks!

laurence-myers commented 2 years ago

You might need to explicitly call each decorator method. Does @(jf.object().required()) work?

On Fri, 24 Sep. 2021, 3:22 am Randy H, @.***> wrote:

I have two classes, one referencing another:

class Address { @(jf.string().required().label("Address Line 1").min(1)) line1!: string;

@(jf.string().label("Address Line 2")) line2?: string;

// so on...}class RegisterDetails { // ...

@(jf.object.required()) address_shipping!: Address;}

When I validate with RegisterDetails, all the normal validators (strings, numbers, etc.) work as expected; the nested object is not. Does anyone have any ideas on what's going on? Thanks!

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/joiful-ts/joiful/issues/226, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABQK4MCIIEDR4HRJGGCDSS3UDNO5TANCNFSM5EUFRYGA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

laurence-myers commented 2 years ago

Closing.

kogratte commented 9 months ago

Sorry guys, but I can reproduce the exact same issue, and the answer to the question is a big "nop, it does not work". Why is this issue closed?

kogratte commented 9 months ago

More context.

class Item implements TItem
{
    @object().optional()
    child?: TChild;
}

class Child implements TChild {
   @string().required().min(10).max(30)
    content = "";
}

When invoking validation with the following code

 const result = jf.validateAsClass({ child: { content: "" } }, Item, {
        allowUnknown: true,        
    });

I got a valid result, despite the fact content being clearly invalid.

May it be due to the usage of interface instead of plain objects?

laurence-myers commented 9 months ago

May it be due to the usage of interface instead of plain objects?

Nested objects must be a class, not an interface. This is because interfaces don't exist at runtime, and can't accept decorators. Although you have added decorators to the Child class, there are no decorators on TChild, so no validation occurs.

Here's an example from the unit tests:

https://github.com/joiful-ts/joiful/blob/f0c977ba09b66bb0368b436c8fb478dda7040153/test/unit/examples.test.ts#L56-L76

kogratte commented 9 months ago

Then I guess I have to roll back to the row joi :)

Thanks for the quick reply!

On Wed, 13 Dec 2023, 20:38 Laurence Dougal Myers, @.***> wrote:

May it be due to the usage of interface instead of plain objects?

Nested objects must be a class, not an interface. This is because interfaces don't exist at runtime, and can't accept decorators. Although you have added decorators to the Child class, there are no decorators on TChild, so no validation occurs.

Here's an example from the unit tests:

https://github.com/joiful-ts/joiful/blob/f0c977ba09b66bb0368b436c8fb478dda7040153/test/unit/examples.test.ts#L56

— Reply to this email directly, view it on GitHub https://github.com/joiful-ts/joiful/issues/226#issuecomment-1854592522, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAORHVJGED7MYN5GU57JGJLYJH745AVCNFSM5EUFRYGKU5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TCOBVGQ2TSMRVGIZA . You are receiving this because you commented.Message ID: @.***>

laurence-myers commented 9 months ago

Then I guess I have to roll back to the [raw] joi :)

I'm not sure why. joiful will work if you change this:

    child?: TChild;

To this:

    child?: Child;

Or, if you want to keep it as an interface, pass the class to the decorator options:

    @object({ objectClass: Child }).optional()
    child?: TChild;
kogratte commented 9 months ago

There is a reason I'm using interfaces and not implementation :)

On Sun, 17 Dec 2023, 02:14 Laurence Dougal Myers, @.***> wrote:

Then I guess I have to roll back to the [raw] joi :)

I'm not sure why. joiful will work if you change this:

child?: TChild;

To this:

child?: Child;

Or, if you want to keep it as an interface, pass the class to the decorator options:

@object({ objectClass: Child }).optional()
child?: TChild;

— Reply to this email directly, view it on GitHub https://github.com/joiful-ts/joiful/issues/226#issuecomment-1859004951, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAORHVNVASPDP47C3XWGMQLYJZBN5AVCNFSM5EUFRYGKU5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TCOBVHEYDANBZGUYQ . You are receiving this because you commented.Message ID: @.***>