Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create default [highly nested] object easily? #413

Closed
gdw2 opened this issue Aug 29, 2014 · 10 comments
Closed

Create default [highly nested] object easily? #413

gdw2 opened this issue Aug 29, 2014 · 10 comments
Assignees
Labels
feature New functionality or improvement
Milestone

Comments

@gdw2
Copy link
Contributor

gdw2 commented Aug 29, 2014

I've got a pretty massive and nested Joi structure. I'm wondering if there's an easy way to have it spit out a default object. Something like:

Joi.compile(
    {
        baz: 
            {foo: Joi.string().default('bar')}, 
        beef: Joi.string().default('hi')
    }
).validate({});
{ error: null, value: { beef: 'hi' } }

But instead of just returning { beef: 'hi' }, have it return { baz: { foo: 'bar' }, beef: 'hi' }.

Is this currently possible?

I could create baz using Joi.object().default(...), but then I'd have to specify the entire substructure as the default. This would be more difficult to maintain.

@Marsup
Copy link
Collaborator

Marsup commented Nov 3, 2014

You can kind of work around that with .example(), is it enough ?
What's the use case ?

@gdw2
Copy link
Contributor Author

gdw2 commented Nov 5, 2014

I think .example() has the same limitation as .deafult(), that is, I would need to specify the example for the entire structure up front. A highly nested object wouldn't infer it's example from its children's examples.

Regarding use cases, there are components that I talk to that expect fully fleshed-out data structures (e.g. all elements are required, not optional). Passing '{}' does not validate. In cases where new data structures need to be created, it's nice to have a sane default.

Here is my current workaround which traverses the structure and applies the children defaults to the parent-objects (coffeescript):

# This traverses all nodes in our schema (depth first).  If a node is an object, it gets its default implementation and
# sets that as the objects default.  I think this should be functionality of the joi library itself, but it is not.
schema = traverse(schema).map (x) ->
  # By using after, we go deep first and traverse backwards.
  @after (x2) =>
    # If a schema is an object, update its default
    @update(x2.default(x2.validate({}).value)) if x2?._type == 'object'

It works for me. As far as I'm concerned, this issue can be closed (since it was really a question, and has been answered). Feel free to re-open if you'd like to entertain something like the above making it into the code base. I'm willing to take a stab at it, but don't feel strongly about it.

@gdw2 gdw2 closed this as completed Nov 5, 2014
@Marsup
Copy link
Collaborator

Marsup commented Nov 5, 2014

OK I get it now, I think it should be part of Joi.

@Marsup Marsup reopened this Nov 5, 2014
@jondlm
Copy link

jondlm commented Feb 15, 2015

I have the same need for one of the apps I'm working on. It would be really nice to allow deeply nested defaults as you described. Thanks for taking the time to describe the problem!

@Marsup
Copy link
Collaborator

Marsup commented Feb 15, 2015

I have a pretty good idea what nested is for an object, what do you all consider it should do for an array ?

@trungfinity
Copy link

👍

I think support for objects could be implemented first, array later. I'm happy to create a pull request.

@Marsup
Copy link
Collaborator

Marsup commented Apr 13, 2015

Does that last commit look good according to what you wanted ?

@gdw2
Copy link
Contributor Author

gdw2 commented Apr 13, 2015

Looks good to me. Thanks.

@Marsup Marsup added this to the 6.2.0 milestone Apr 16, 2015
@Marsup Marsup self-assigned this Apr 16, 2015
@Marsup Marsup closed this as completed in 6dcd80e Apr 16, 2015
@danielo515
Copy link
Contributor

Glad to see this is implemented. How can I make use of it?

@hueniverse hueniverse added feature New functionality or improvement and removed request labels Sep 19, 2019
@lock
Copy link

lock bot commented Jan 9, 2020

This thread has been automatically locked due to inactivity. Please open a new issue for related bugs or questions following the new issue template instructions.

@lock lock bot locked as resolved and limited conversation to collaborators Jan 9, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
feature New functionality or improvement
Projects
None yet
Development

No branches or pull requests

6 participants