Why does Joi validate an array of objects with "contains a duplicate value"?
Asked Answered
K

1

7

My schema is:

const scenerioSchema = Joi.object({
  drawingNode: Joi.object({
    moduleRackOutputs: Joi.array()
      .items(
        Joi.object({
          moduleId: Joi.string().required()
        })
      )
      .unique((a, b) => a.moduleId !== b.moduleId)
  })
})

My data is:

const mockScenario1 = {
  drawingNode: {
    moduleRackOutputs: [
      {
        moduleId: 'module1'
      },
      {
        moduleId: 'module2'
      }
    ]
  }
}

When I validate with:

const validationResponse = scenerioSchema.validate(mockScenario1)

I get:

{
      validationResponse: {
        value: { drawingNode: [Object] },
        error: [Error [ValidationError]: "drawingNode.moduleRackOutputs[1]" contains a duplicate value] {
          _original: [Object],
          details: [Array]
        }
      }
    }

But (a) that's not true - the items are not duplicates and (b) I want an error to occur if the moduleId is different.

What am I doing wrong?

Kierkegaardian answered 11/1, 2022 at 16:23 Comment(1)
Change the !== to === in the unique functionRao
U
1

The Solution

As @Ankh suggested,
the solution to your problem is to replace the !== with ===.

Why is this the solution?

When you did the !==, what you essentially told Joi is:
"All array elements must have the SAME unique key!" So here are some example data that would pass:

// Example 1: would pass!
const arr = [ { moduleId: 0 } ];

// Example 2: would pass!
const arr = [ { moduleId: 0 } , { moduleId: 0 }]

// Example 3: would pass!
const arr = [ { moduleId: 0 } , { moduleId: 0 }, { moduleId: 0 }] // and so on...

These following examples, however, would fail:

// Example 4: would fail...
const arr = [ { moduleId: 0 }, { moduleId: 1 } ];

// Example 5: would fail...
const arr = [ { moduleId: 1 } , { moduleId: 2 } , { moduleId: 3 }]

// Example 6: would fail...
const arr = [ { moduleId: 1 } , { moduleId: 1 } , { moduleId: 2 }]

That is because Joi runs the "unique" validation against all other items in the array, and says: "I'm gonna declare DUPLICATE whenever I see an element j that is !== to element i", and what you want is the exact opposite.

Urena answered 27/7, 2022 at 4:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.