Reputation: 10554
I have object in wgich I want to validated its values with some computed value. for now I am doing it javascript way but I want to do it by using Joi.
{
"scoreThreshold": 1,
"questions": [
{
"question": "someString",
"answer": 1,
"factor": 2
},
{
"question": "someString"
"answer": 3
},
{
"question": "someString",
"answer": 0,
"factor": 3
},
{
"question": "someString"
"answer": 1
}
],
}
I am validating it using javascript
var validator = function(doc) {
var maxScore = 0
for (var item of doc.questions) {
maxScore += 1000 * (item.factor == undefined ? 1: item.factor)
}
if (maxScore == 0) {
throw new Error("maxScore is 0")
}
if (doc.scoreThreshold > maxScore) {
throw new Error("scoreThreshold more than maxScore")
} else if ((doc.scoreThreshold / maxScore) > 0.95) {
throw new Error("scoreThreshold too close to maxScore")
}
}
How can I do this validation the Joi
way?
Upvotes: 1
Views: 1556
Reputation: 10554
We can do this in Joi way using adjust
option of Joi.ref()
var calculateMaxScore = function(questions) {
return (questions || []).reduce((t, e) => t + 1000 * (e.factor == undefined ? 1: e.factor), 0)
}
var schema = Joi.object({
"scoreThreshold": Joi.number().integer()
.greater(0)
.less(Joi.ref('questions', { adjust: (v) => calculateMaxScore(v) * 0.95 }))
.required(),
"questions": Joi.array().items(Joi.object({
"question": JJoi.string().min(1)).required(),
"answer": Joi.number().integer().min(0).required(),
"factor": Joi.number().integer().min(0)
}))
.required()
})
Upvotes: 1
Reputation: 20039
You can use any.custom()
for custom validation
any.custom(method, [description])
var schema = Joi.object()
.keys({
scoreThreshold: Joi.number(),
questions: Joi.array().items(
Joi.object({
question: Joi.string(),
answer: Joi.number(),
factor: Joi.number()
})
)
})
.custom((doc, helpers) => {
var maxScore = 0;
for (var item of doc.questions) {
maxScore += 1000 * (item.factor == undefined ? 1 : item.factor);
}
if (maxScore == 0) {
throw new Error("maxScore is 0");
}
if (doc.scoreThreshold > maxScore) {
throw new Error("scoreThreshold more than maxScore");
} else if (doc.scoreThreshold / maxScore > 0.95) {
throw new Error("scoreThreshold too close to maxScore");
}
// Return the value unchanged
return doc;
});
Upvotes: 1