最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Using Joi, require one of two fields to be non empty - Stack Overflow

programmeradmin9浏览0评论

If I have two fields, I'd just like to validate when at least one field is a non empty string, but fail when both fields are empty strings.

Something like this does not validate

var schema = Joi.object().keys({
    a: Joi.string(),
    b: Joi.string()
}).or('a', 'b');

When validating against

{a: 'aa', b: ''}

The or condition only tests for the presence of either key a or b, but does test whether the condition for a or b is true. Joi.string() will fail for empty strings.

Here is gist with some test cases to demonstrate

/?gist=84c49d8b81025ce68cfb

If I have two fields, I'd just like to validate when at least one field is a non empty string, but fail when both fields are empty strings.

Something like this does not validate

var schema = Joi.object().keys({
    a: Joi.string(),
    b: Joi.string()
}).or('a', 'b');

When validating against

{a: 'aa', b: ''}

The or condition only tests for the presence of either key a or b, but does test whether the condition for a or b is true. Joi.string() will fail for empty strings.

Here is gist with some test cases to demonstrate

http://requirebin.com/?gist=84c49d8b81025ce68cfb

Share Improve this question edited Mar 5, 2015 at 10:50 Brendan asked Mar 4, 2015 at 20:59 BrendanBrendan 8291 gold badge8 silver badges13 bronze badges
Add a comment  | 

6 Answers 6

Reset to default 33

Code below worked for me. I used alternatives because .or is really testing for the existence of keys and what you really wanted was an alternative where you would allow one key or the other to be empty.

var console = require("consoleit");
var Joi = require('joi');

var schema = Joi.alternatives().try(
  Joi.object().keys({
    a: Joi.string().allow(''),
    b: Joi.string()
    }),
  Joi.object().keys({
    a: Joi.string(),
    b: Joi.string().allow('')
    })
);

var tests = [
  // both empty - should fail
  {a: '', b: ''},
  // one not empty - should pass but is FAILING
  {a: 'aa', b: ''},
  // both not empty - should pass
  {a: 'aa', b: 'bb'},
  // one not empty, other key missing - should pass
  {a: 'aa'}
];

for(var i = 0; i < tests.length; i++) {
  console.log(i, Joi.validate(tests[i], schema)['error']);
}

An alternative way of using Joi.when() that worked for me:

var schema = Joi.object().keys({
  a: Joi.string().allow(''),
  b: Joi.when('a', { is: '', then: Joi.string(), otherwise: Joi.string().allow('') })
}).or('a', 'b')

.or('a', 'b') prevents a AND b being null (as opposed to '').

If you want to express the dependency between 2 fields without having to repeat all other parts of the object, you could use when:

var schema = Joi.object().keys({
  a: Joi.string().allow(''),
  b: Joi.string().allow('').when('a', { is: '', then: Joi.string() })
}).or('a', 'b');

You could just use .xor('a', 'b') instead .or('a', 'b'):

var schema = Joi.object().keys({
    a: Joi.string(),
    b: Joi.string()
}).xor('a', 'b');

This allows to be or only a or only b but not both, and not none

if your object is:
{ a: 'non-empty' } or { b: 'non-empty' }
will pass

if your object is:
{ a: '', b: '' } or { a: 'non-empty', b: 'non-empty' } 
will NOT pass

if your object is:
{ a: ''} or { b: '' } 
will NOT pass

if your object is:
{ a: '', b: 'non-empty' } or { a: 'non-empty', b: '' } 
will NOT pass

if your object is:
{ }
will NOT pass

the problem I faced with https://stackoverflow.com/a/61212051/15265372 answer is that if both fields are given you won't face any errors, if you want to fix that you need to replace or with xor.

&. Simply u can use '.and()'

  • it will not pass if either one of the fields is empty
var schema = Joi.object().keys({
   a: Joi.string(),
   b: Joi.string()
}).and('a', 'b');````
发布评论

评论列表(0)

  1. 暂无评论