What is the best way to enforce constraints on three keys when validating an object using Joi?

Currently experimenting with Joi for object validation.
Able to validate objects with constraints on two keys using any.when().
Now looking to implement validation with constraints on three keys, for example:

var object = {
    dynamicPrize: false,
    entryFee: 6,
    isGold: false,
    someOtherKey: someValue
}

// Constraints on three keys
if (object.dynamicPrize && object.entryFee > 0 && !object.isGold) {
    throw new Error("This should not happen")
}

Seeking guidance on validating this scenario using Joi without resorting to an if, else statement.

Answer №1

To ensure the validation of objects, we have an alternative option to use any.when(). This method involves passing Joi.object() as an argument within the any.when() function.

const Joi = require('@hapi/joi');

const validationSchema = Joi
  .object({
    dynamicPrize: Joi
      .boolean()
      .required(),
    entryFee: Joi
      .number()
      .integer()
      .min(1)
      .required(),
    isGold: Joi
      .boolean()
      .required(),
  })
  .when(Joi.object({
    dynamicPrize: Joi.boolean().valid(true),
    entryFee: Joi.number().integer().min(1),
    isGold: Joi.boolean().valid(false),
  }), {
    then: Joi.any().forbidden()
      .error(new Joi.ValidationError('', {
        message: 'This should not happen',
      })),
  });

const object1 = {
  dynamicPrize: true,
  entryFee: 6,
  isGold: false,
};

const validateObject1 = validationSchema.validate(object1);
console.log('Object1');
if (validateObject1.error) {
  console.error(validateObject1.error);
} else {
  console.info('validation success');
}
console.log();

const object2 = {
  dynamicPrize: false,
  entryFee: 6,
  isGold: false,
};

const validateObject2 = validationSchema.validate(object2);
console.log('Object2');
if (validateObject2.error) {
 console.error(validateObject2.error);
} else {
  console.info('validation success');
}

The resulting output will resemble the following format.

Object1
{ ValidationError
    at Object.<anonymous> (/home/wisnu/Labs/nodejs/joi/index.js:23:14)
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)
    at startup (internal/bootstrap/node.js:283:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:622:3)
  _original: undefined,
  details: { message: 'This should not happen' } }

Object2
validation success

Answer №2

Implementing validation with the valid() and greater() methods

const schema = Joi.object({
  dynamicPrize: Joi.boolean().valid(true),
  entryFee: Joi.number().greater(0),
  isGold: Joi.boolean().valid(false)
});

Visit the live demo on stackblitz

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is the jQuery AJAX call using POST method being retrieved as $_GET?

Below is a snippet of code that I've successfully implemented: <script type="text/javascript"> $(document).ready(function() { // Initializing the table $('#table_1').tableDnD({ onDrop: function(table, row) { $.tab ...

Insert item at the end of the box and move all elements upwards

Hello! I'm experimenting with creating something using javascript's createElement method. My goal is to achieve an effect similar to this image: https://i.stack.imgur.com/itKUK.gif Currently, my code is functional, but the animation goes from to ...

What is the best way to update just the image path in the source using jQuery?

I am currently working on implementing a dark mode function for my website, and I have successfully adjusted the divs and other elements. However, I am facing an issue with changing the paths of images. In order to enable dark mode, I have created two sep ...

What is the best way to fulfill a promise after a CSV file has finished being read?

I have been utilizing the 'fast-csv' module that can be found at this link (https://www.npmjs.org/package/fast-csv), but I am open to switching to a different one. I attempted promised-csv (https://www.npmjs.org/package/promised-csv) but I had tr ...

What is the best way to convert an array to JSON in Swift?

I am having trouble extracting the value "maxtemp_c" from a JSON request. This is my attempt so far, but I keep encountering issues when trying to parse the JSON data and end up with a nil value: //I have the URL of the json let url = URL(string: "http:/ ...

Utilizing jq for finding a parent element based on a specific child key/value pair

How can I use jq to select a parent object that contains a child object meeting two filter requirements? For instance, I want to choose all Subnets elements with a child tag having key "Name" and value "TheName". There are two subnets in my example - one ...

Queueing up file downloads through a web browser

When trying to download multiple files from a server, I am required to queue them up instead of downloading in parallel. Unfortunately, I do not have access to the download server, so my only option is to work with the browser. Is there an API available t ...

Exploring the syntax of typescript when using createContext

Just starting out with typescript and I have some questions. Could someone break down the syntax used in this code snippet for me? What is the significance of having two groups containing signIn, signOut, and user here? Is the first group responsible fo ...

I'm confused as to why the icon color isn't changing on the Blogger homepage for each individual user

I'm experimenting with changing the eye color based on visitor count. It works perfectly fine on static posts in my Blogger, but it fails to update the eye color properly on my homepage according to the set numeric values. Instead of displaying differ ...

Can JSON.parse be used on only a portion of an object in JavaScript?

Currently, I am facing an issue with a lengthy JSON file that I am fetching from a URL using https.request. Upon attempting to parse the string with JSON.parse, I encounter an "Unexpected end of JSON input" error. It appears that there is a limit to the ...

What is the best way to retrieve a value in Ajax?

I'm trying to assign the result of an MVC controller method to a variable. function someFunction(){ var result; $.Ajax{ //??? } return result; } //Contrast with C++ int f() { //just! return result; } Post Script: Th ...

Having issues with Vue.js when using Vue-strap Radio Buttons

While developing my web application with vue.js, I encountered an issue with radio buttons when I switched to using bootstrap style. I understand that I need to use vue-strap for proper data binding with bootstrap styled radio buttons in vue.js, but I am s ...

What is the reason for the find() method not displaying the most recent data from a MongoDB database in an Express.js application?

Upon calling the app.post('/form-submit', funtion(req, res)) method, my expectation is for it to first save the data using save(). This works fine, but then when I call the find() method, it shows all the data from the mongoDB database except for ...

Enhance your browsing experience by inputting valuable information into the

I am looking to enhance a text box by adding values. The text box already has a default value of 10, and I want to create a button that will add new text boxes with a limit of 4. My goal is to continuously add values from text box 1 to text box 4. For exa ...

What steps can be taken to ensure that a function is executed in order to delegate the process forward?

In my JavaScript code, I have a series of functions that need to be executed in a specific order. One function may return a value synchronously, while others do not return anything or return an Observable result asynchronously. How can I ensure that each ...

Protractor Error: Identifier Unexpectedly Not Found

I've encountered a slight issue with importing and exporting files while working on Protractor tests. HomePage.js export default class HomePage { constructor() { this.path = 'http://automationpractice.com/index.php'; this.searchQ ...

Retrieve JSON elements from a MYSQL database where the JSON data is present

In my database, I have a table orders which contains orders.items in JSON format. An example of the orders.items cell looks like this: { "10": { "name": "item 1", "step": "1", "price": "140", "amount": "4", ...

Check off all checkboxes and send their values to an AJAX script using a table

I currently have a table set up with checkboxes in the first column. By checking these boxes, an AJAX script is triggered that updates a PHP session variable with the selected values. This functionality is working smoothly. However, I am now looking to enh ...

Utilizing attributes as scope properties within AngularJS

I am currently working on a directive and I need to pass the Attributes (Attrs) to the $scope, however, I am facing some difficulties in achieving this. Specifically, my goal is to assign attributes in my template based on the name set in my date-picker ta ...

Troubleshooting in WebStorm: Uncovering the Root Cause Within an npm Package (node:36378) [DEP0005] - Warning: Deprecation Warning

Over the past 6 months, I've been encountering an error that seems to have surfaced after an update to node.js. (node:36378) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), ...