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

javascript - HapiJoi validation with nested object - Stack Overflow

programmeradmin1浏览0评论

I have the following validation on one of my routes:

payload: {
    keywordGroups: Joi.array().items(Joi.object().keys({
        language: Joi.string().required(),
        containsAny: Joi.array().items(Joi.string()).default([]).when('containsAll', { is: [], then: Joi.required() }),
        containsAll: Joi.array().items(Joi.string()).default([]).when('containsAny', { is: [], then: Joi.required() }),
        notContainsAll: Joi.array().items(Joi.string()).default([]),
        notContainsAny: Joi.array().items(Joi.string()).default([])
    })).required(),
}

I'm trying to make it so that containsAny or containsAll have to include at least one string. If containsAny is empty, containsAll should have at least one item. And if containsAll is empty, containsAny should at least include one item.

But it seems Joi.when doesn't really work when it es to an array of objects.

I have the following validation on one of my routes:

payload: {
    keywordGroups: Joi.array().items(Joi.object().keys({
        language: Joi.string().required(),
        containsAny: Joi.array().items(Joi.string()).default([]).when('containsAll', { is: [], then: Joi.required() }),
        containsAll: Joi.array().items(Joi.string()).default([]).when('containsAny', { is: [], then: Joi.required() }),
        notContainsAll: Joi.array().items(Joi.string()).default([]),
        notContainsAny: Joi.array().items(Joi.string()).default([])
    })).required(),
}

I'm trying to make it so that containsAny or containsAll have to include at least one string. If containsAny is empty, containsAll should have at least one item. And if containsAll is empty, containsAny should at least include one item.

But it seems Joi.when doesn't really work when it es to an array of objects.

Share edited Nov 18, 2015 at 20:58 Gergo Erdosi 42.1k21 gold badges121 silver badges95 bronze badges asked Nov 18, 2015 at 2:27 woutr_bewoutr_be 9,73225 gold badges82 silver badges130 bronze badges 3
  • Try swapping your is: [] for Joi.array().length(0). the documentation suggests the is condition should be a Joi type. github./hapijs/joi/blob/master/API.md#anywhenref-options – Cuthbert Commented Nov 18, 2015 at 21:38
  • I think you're also creating a circular dependency here. see this thread: github./hapijs/joi/issues/588 – Cuthbert Commented Nov 18, 2015 at 21:42
  • @Cuthbert I think my main question was on how I could reference those fields correctly, seeing that they're in an array of objects. – woutr_be Commented Nov 19, 2015 at 5:16
Add a ment  | 

1 Answer 1

Reset to default 6

You need to use Joi.alternatives() otherwise you will create a circular dependency as described in this issue.

In your is condition in the when(), you need to specify a Joi type instead of just an empty array. This example works:

import * as Joi from 'joi';

var arraySchema = Joi.array().items(Joi.object().keys({
    first: Joi.array().items(Joi.number()).default([])
        .when('second', {is: Joi.array().length(0), then: Joi.array().items(Joi.number()).required().min(1)}),
    second: Joi.array().items(Joi.number()).default([])
}));

var altArraySchema = Joi.array().items(Joi.object().keys({
    first: Joi.array().items(Joi.number()).default([]),
    second: Joi.array().items(Joi.number()).default([])
        .when('first', {is: Joi.array().length(0), then: Joi.array().items(Joi.number()).required().min(1)}),
}));

var obj = [
    {
        first: [],
        second: []
    }
];

var finalSchema = Joi.alternatives(arraySchema, altArraySchema);

var result = Joi.validate(obj, finalSchema);

console.log(JSON.stringify(result, null, 2));

The variable obj will fail the validation because both first and second are empty. Making either of them non-empty will pass the validation check.

发布评论

评论列表(0)

  1. 暂无评论