Node Joi: Value of a joi key must match with one object key in a joi array

Viewed 510

This is my Joi schema

const createRoom = {
  body: {
    createdBy: Joi.string().required(),
    members: Joi.array().min(2).max(2).items(
      Joi.object().keys({
        id: Joi.string().required(),
        name: Joi.string().required(),
      })
    ).unique('id').required()
  }
}

What i want is

The value of createdBy must match with one unique object id in members array

Example

This input should pass

{
  createdBy: 'abcd1234',
  members: [
    {
      id: 'abcd1234',
      name: "john"
    },
    {
      id: 'xyz1234',
      name: "john"
    }
  ]
}

This input should fail

{
  createdBy: 'abcd1234',
  members: [
    {
      id: 'bcdf1234',
      name: "john"
    },
    {
      id: 'xyz1234',
      name: "john"
    }
  ]
}

Is this possible with joi? I didn't find anything like this in Joi Docs.

1 Answers

You can combine array.has with ref:

const schema = Joi.object({
 createdBy: Joi.string().required(),
 members: Joi.array().min(2).max(2).items(
    Joi.object().keys({
        id: Joi.string().required(),
        name: Joi.string().required(),
    }))
    .has(Joi.object({ 
        id: Joi.string().required().valid(Joi.ref('$createdBy')),
        name: Joi.string()
    }))
    .unique('id')
})

With array.has you are saying that you want at least one of those objects inside the array. And Joi.ref lets access you any value of the current object.

This means that the following object will pass:

const validObj = {
  createdBy: 'abcd1234',
  members: [
    {
      id: 'abcd1234',
      name: "john"
    },
    {
      id: 'xyz1234',
      name: "john"
    }
  ]
}

schema.validate(validObj, { context: validObj })

And this will fail:

const invalidObj = {
  createdBy: 'abcd1234',
  members: [
    {
      id: 'xxxx',
      name: "john"
    },
    {
      id: 'xyz1234',
      name: "john"
    }
  ]
}

schema.validate(invalidObj, { context: invalidObj })

This will also fail since there is a duplicate:

const invalidObj = {
  createdBy: 'abcd1234',
  members: [
    {
      id: 'abcd1234',
      name: "john"
    },
    {
      id: 'abcd1234',
      name: "john"
    }
  ]
}

schema.validate(invalidObj, { context: invalidObj })
Related