Mark all properties as required or not Joi Mark all properties as required or not Joi express express

Mark all properties as required or not Joi


A better way will be using any.fork(paths, adjuster).

Returns a new schema where each of the path keys listed have been modified where:

  • paths - an array of key strings, a single key string, or an array of arrays of pre-split key strings. Key string paths use dot . to indicate key hierarchy.
  • adjuster - a function using the signature function(schema) which must return a modified schema. For example, (schema) => schema.required().

The method does not modify the original schema.

ex:

// define the objectconst schemaObj = {    name: Joi.string(),    lastName: Joi.string(),    email: Joi.string().email(),    password: Joi.string(),    address: Joi.string(),    city: Joi.string(),    district: Joi.string()};// no need to use fork here every obj is already not requiredconst allUnreqJoiObj = Joi.object(schemaObj);// use of fork to modify it// fork for all keysconst allReqJoiObj = Joi.object(schemaObj).fork(Object.keys(schemaObj), (schema) => schema.required());console.log(allReqJoiObj.validate({'city': 'some city'}));// fork for selected keys const fewReqJoiObj = Joi.object(schemaObj).fork(['email', 'password'], (schema) => schema.required());console.log(fewReqJoiObj.validate({'city': 'some city'}));

if you already have a schema where some or all the keys is required then use fork and make them optional

ex:

const schemaObj = {  name: Joi.string().required(),  lastName: Joi.string().required(),};const allOptional = Joi.object(schemaObj).fork(Object.keys(schemaObj), (schema) => schema.optional());const nameOptional = Joi.object(schemaObj).fork(['name'], (schema) => schema.optional());


I guess you are tackling the problem in a wrong way. Schema should generally depict how your types are in DB. for example if a first name is required, it will always be required irresepective if it is create or update. So in case of update you will fetch the item from db and apply changes on top of that and then send it for validation.

If you really want to do it this way, you could pass context to your validate function which can be accessed from your joi schema using $ sign. You have two choices here, either apply if else condition for each property which will make your schema look ugly OR have all togather two version of schema and choose depending upon value of the context passed. Something like this

const Joi = require("@hapi/joi");const schemaA = Joi.object().keys({  "name": Joi.string().required(),  "lastName": Joi.string().required(),  "email": Joi.string().email().required(),  "password": Joi.string().required(),  "address": Joi.string().required(),  "city": Joi.string().required(),  "district": Joi.string().required()});const schemaB = Joi.object().keys({  "name": Joi.string(),  "lastName": Joi.string(),  "email": Joi.string().email(),  "password": Joi.string(),  "address": Joi.string(),  "city": Joi.string(),  "district": Joi.string()});function ChooseSchema() {  return Joi.when(Joi.ref("$isNew"), {    "is": true,    "then": schemaA,    "otherwise": schemaB  });}console.log(ChooseSchema().validate({"name": "ashish"}, {"context": {"isNew": true}}));console.log(ChooseSchema().validate({"name": "ashish"}, {"context": {"isNew": false}}));