Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Joi validation set default as empty object

Tags:

joi

hapi.js

I'm running into an issue (or what I believe to be one) with Joi validation. I'm trying to assign a value to a non-existent key if it's been passed as part of the request body.

So for example:

parameters: Joi.object().keys({
  keyA: Joi.string().allow('').allow(null).default(null),
  keyB: Joi.object().keys({
    b1: Joi.string(),
    b2: Joi.string(),
    b3: Joi.object().keys({
      b3_1: Joi.string(),
      b3_2: Joi.string(),
      b3_3: Joi.string()
    })
  }).default({}),
  keyC: Joi.object().keys({
    c1: Joi.number(),
    c2: Joi.number(),
    c3: Joi.boolean(),
    c4: Joi.boolean()
  }).default({}),
  keyD: Joi.object().keys({
    d1: Joi.number(),
    d2: Joi.number()
  }).default({}),
  keyE: Joi.object().keys({
    e1: Joi.number()
  }).default({}) 
}).allow(null)

So to be specific if I were to pass in:

{
  keyA: "foo",
  keyD: {
    d1: 21.9,
    d2: 21.1
  },
  keyE: {
    e1: 42
  }
}

I would get this in return

{
  keyA: "foo",
  keyB: {},
  keyC: {},
  keyD: {
    d1: 21.9,
    d2: 21.1
  },
  keyE: {
    e1: 42
  }
}

With :eyes: on the empty objects. What am I missing with the Joi.default() method? Am I overextending what Joi is meant for?

like image 278
bneigher Avatar asked Oct 14 '25 03:10

bneigher


1 Answers

I'll start by pointing out that the schema in your question isn't valid JavaScript, you've closed a few too many brackets before declaring the rule for keyC. I'll assume this is simply a formatting error with the question and your actual schema is currently valid.

Secondly, there's nothing wrong with how you've declared your defaults.. it works just fine. I'll assume it's the way you're validating the schema which is the problem.

Try running this. I've mimicked the validation method in the docs for default().

const schema = Joi.object().keys({
    keyA: Joi.string().allow('').allow(null).default(null),
    keyB: Joi.object().keys({
        b1: Joi.string(),
        b2: Joi.string(),
        b3: Joi.object().keys({
            b3_1: Joi.string(),
            b3_2: Joi.string(),
            b3_3: Joi.string()
        })
    }).default({}),
    keyC: Joi.object().keys({
        c1: Joi.number(),
        c2: Joi.number(),
        c3: Joi.boolean(),
        c4: Joi.boolean()
    }).default({}),
    keyD: Joi.object().keys({
        d1: Joi.number(),
        d2: Joi.number()
    }).default({}),
    keyE: Joi.object().keys({
        e1: Joi.number()
    }).default({})
}).allow(null);

Joi.validate({
    keyA: "foo",
    keyD: {
        d1: 21.9,
        d2: 21.1
    },
    keyE: {
        e1: 42
    }
}, schema, (err, value) =>
{
    if (err)
        throw err;

    console.log(value);
});

I get this in the console:

{
    keyA :'foo',
    keyD: {
        d1: 21.9,
        d2: 21.1
    },
    keyE: {
        e1: 42
    },
    keyB: {},
    keyC: {}
}

The keys are unlikely to look ordered like your expected output, but that shouldn't matter as object keys are not ordered anyway.

like image 126
Ankh Avatar answered Oct 17 '25 20:10

Ankh



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!