Joi: .optional() does not respect null.

Created on 11 Dec 2016  路  5Comments  路  Source: sideway/joi

Node 7.2.0, Joi 10.0.5.

The .optional() key does not respect null but it should. Example:

var joi = require("joi");

joi.validate({
    test: null
}, {
    test: joi.number().integer().optional()
}, function (err, value) {
    console.log("err", err);
});

Fails with '"test" must be a number".

Example use case: Optional fields submitted from a form, being processed by Joi schema validation (e.g. bookshelf-modelbase has this built in). Consequently, even when being coerced to null, Joi cannot actually be used to validate form inputs, and so validation of optional parameters must be handled explicitly, thus defeating some of the usefulness of Joi. Example attempt:

    // say req is an express request:
    var paramsFromForm {
       exampleField: req.body.exampleField,
       exampleOptional: req.body.exampleOptional == "" ? null : req.body.exampleOptional
    }

Will fail with validation schemas like:

    {
        exampleField: Joi. ..., 
        exampleOptional: Joi.number().integer().optional()
    }

It's a common use case and becomes extremely cumbersome.

What should happen is null/undefined should be implicitly allowed when .optional() is specified.

Note that in the specific case of e.g. Bookshelf it is not enough to set the parameter to undefined rather than null, as this will ultimately cause the value to be unchanged in the DB rather than set to NULL. So that is not a workaround for that usage.

Even worse is that in some use cases you can't just validate optional parameters explicitly, you must drop Joi entirely, because leaving a field out of a schema produces "'field' is not allowed":

var joi = require("joi");

joi.validate({
    test: null
}, {
}, function (err, value) {
    console.log("err", err);
});

That fails.

So as far as I can tell there is actually no way to use Joi at all if one of the fields is allowed to be null or a value. That's kind of a big problem...

non issue

Most helpful comment

Correct. It didn't look like a feature request, I'm very unlikely to change it as it would break many people's apps.

All 5 comments

it should

According to who ? Please read the docs, it's 3 lines and already answered.

According to me. That was a feature request, not a bug report...

I think I see the way to do this. It's:

Joi.number().integer().allow(null).optional()

Correct?

So: allow(null) allows null, and optional() allows undefined. Is my understanding correct?

Correct. It didn't look like a feature request, I'm very unlikely to change it as it would break many people's apps.

Makes sense to me, and it doesn't need to change, this works great. Thanks!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

neroaugustus1 picture neroaugustus1  路  4Comments

JbIPS picture JbIPS  路  4Comments

alekbarszczewski picture alekbarszczewski  路  3Comments

PaunPrashant picture PaunPrashant  路  3Comments

chrisegner picture chrisegner  路  4Comments