p0tta
p0tta

Reputation: 1651

How to validate the items of an array with ajv?

I have my validator defined as follows

var abcSchemaValidator = {
"type": "object",
"required": [],
"properties": {
    "remarks": {
        "type": "string",
        "maxLength": 2000
    },
    "comment": {
        "type": "string",
        "maxLength": 2000
    }
}
};

In my code where I am applying these validations, I am doing something like this

modelObject.remarks = sometext;

modelObject.parent[0].comment

So when I run my ajv validation using the following code

let validate = ajv.compile(schema);
let validResult = validate(data);

The remarks is validated properly whereas the comment is not. I can see why the remarks is straightforward but I am not sure how to make the comment work. Should I change the comment to parent.comment in the schemaValidator? I tried changing to parent[0].comment but that didn't work.

Upvotes: 0

Views: 5649

Answers (1)

customcommander
customcommander

Reputation: 18901

Your schema doesn't define any rule for parent nor does it forbid additional properties. As is your schema is working as expected.

As far as I can tell, parent is:

  1. A non-required but expected property of an object
  2. An array of objects, each of which can have a comment property which schema is the same as remarks

First, let's define something we can re-use:

ajv.addSchema({
  $id: 'defs.json',
  definitions: {
    userInput: {
      type: 'string',
      maxLength: 10
    }
  }
});

Then, let's use this common definitions to redefine remarks and define parent

const validate = ajv.compile({
  $id: 'main.json',
  type: 'object',
  properties: {
    remarks: {$ref: 'defs.json#/definitions/userInput'},
    parent: {
      type: 'array',
      items: {
        type: 'object',
        properties: {
          comment: {$ref: 'defs.json#/definitions/userInput'}
        }
      }
    }
  }
});

And now let's validate some data:

// OK
console.assert(validate({remarks: 'foo'}),
  JSON.stringify(validate.errors, null, 2));

// ERR: `remarks` is too long
console.assert(validate({remarks: 'foobarbazbat'}),
  JSON.stringify(validate.errors, null, 2));

// OK: schema doesn't say `parent` can't be empty
console.assert(validate({remarks: 'foo', parent: []}),
  JSON.stringify(validate.errors, null, 2));

// OK: schema doesn't say `parent` elements MUST have a `comment` property
console.assert(validate({remarks: 'foo', parent: [{}]}),
  JSON.stringify(validate.errors, null, 2));

// OK
console.assert(validate({remarks: 'foo', parent: [{comment: 'foo'}]}),
  JSON.stringify(validate.errors, null, 2));

// ERR: `comment` is too long
console.assert(validate({remarks: 'foo', parent: [{comment: 'foobarbazbat'}]}),
  JSON.stringify(validate.errors, null, 2));
<script src="https://cdnjs.cloudflare.com/ajax/libs/ajv/6.10.2/ajv.min.js"></script>
<script>
const ajv = new Ajv();

ajv.addSchema({
  $id: 'defs.json',
  definitions: {
    userInput: {
      type: 'string',
      maxLength: 10
    }
  }
});

const validate = ajv.compile({
  $id: 'main.json',
  type: 'object',
  properties: {
    remarks: {$ref: 'defs.json#/definitions/userInput'},
    parent: {
      type: 'array',
      items: {
        type: 'object',
        properties: {
          comment: {$ref: 'defs.json#/definitions/userInput'}
        }
      }
    }
  }
});
</script>

Upvotes: 1

Related Questions