skip to Main Content

I’m using ajv to validate a JSON instance using a fairly simple schema, but that is failing on the array type with the following message:

"this must be equal to one of the allowed values"

Problem is, my value is one of the allowed values. This seems like such a simple problem but I’ve not yet found a solution. Here’s my code:

const Ajv = require("ajv");
const ajv = new Ajv();

const schema = {
  type: "object",
  properties: {
    count: { type: "integer" },
    name: { type: "string" },
    bass: {
      type: "array",
      items: {
        type: "string",
      },
      enum: ["Ambush Custom Bass", "MTD", "Ken Smith", "Sadowsky"],
    },
  },
  required: ["count"],
};

const validate = ajv.compile(schema);

const data = {
  count: 1,
  name: "Andy",
  bass: ["MTD"],
};

const valid = validate(data);

console.log("valid: ", valid);

if (!valid) console.log(validate.errors);

Thanks for your help.

2

Answers


  1. Chosen as BEST ANSWER

    Well, as usual, I had to first ask the question to the masses so I could figure it out on my own. I don't know if it's the right way, but here's what I did:

    First, remove the keyword for enum, like so:

    ajv.removeKeyword("enum");
    

    Next, add the enum keyword back, and with it, your custom validation function:

    ajv.addKeyword({
      keyword: "enum",
      validate: (schema, data, value, other) => {
        // custom validation goes here
      }
    });
    

    Finally, I found that the validate function here doesn't give you the option of adding detailed error messaging (or, if it does, I couldn't figure out how to do it), so I created an error array, then pushed entries into that array, with each entry being an object that includes other.instancePath. Then when iterating through the validation.errors array, I combine the more detailed messaging with ajv's errors so I can have custom error messaging along with the error details ajv provides. I hope that makes sense; if not, give me a holler, and I'll further explain.


  2. there is actually a much simpler solution: add the enum values under items field:

    ...
    const schema = {
      type: "object",
      properties: {
        count: { type: "integer" },
        name: { type: "string" },
        bass: {
          type: "array",
          items: {
            type: "string",
            enum: ["Ambush Custom Bass", "MTD", "Ken Smith", "Sadowsky"],
          },
        },
      },
      required: ["count"],
    };
    ...
    

    This way you don’t need to remove/add enum keyword

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search