Empty values validation in json schema using AJV
Asked Answered
V

6

10

I am using Ajv for validating my JSON data. I am unable to find a way to validate empty string as a value of a key. I tried using pattern, but it does not throw appropriate message.

Here is my schema

{
    "type": "object",
    "properties": {
        "user_name": { "type": "string" , "minLength": 1},
        "user_email": { "type": "string" , "minLength": 1},
        "user_contact": { "type": "string" , "minLength": 1}
    },
    "required": [ "user_name", 'user_email', 'user_contact']
}

I am using minLength to check that value should contain at least one character. But it also allows empty space.

Vidar answered 25/8, 2017 at 19:50 Comment(0)
V
4

Right now there is no built in option in AJV to do so.

Vidar answered 24/11, 2017 at 10:39 Comment(0)
T
17

You can do:

ajv.addKeyword('isNotEmpty', {
  type: 'string',
  validate: function (schema, data) {
    return typeof data === 'string' && data.trim() !== ''
  },
  errors: false
})

And in the json schema:

{
  [...]
  "type": "object",
  "properties": {
    "inputName": {
      "type": "string",
      "format": "url",
      "isNotEmpty": true,
      "errorMessage": {
        "isNotEmpty": "...",
        "format": "..."
      }
    }
  }
}
Twelfth answered 14/2, 2018 at 2:39 Comment(1)
What is significance of errors: false in this. Couldn't find from the specificationsTerri
T
5

I found another way to do this using "not" keyword with "maxLength":

{
  [...]
  "type": "object",
  "properties": {
    "inputName": {
      "type": "string",
      "allOf": [
        {"not": { "maxLength": 0 }, "errorMessage": "..."},
        {"minLength": 6, "errorMessage": "..."},
        {"maxLength": 100, "errorMessage": "..."},
        {"..."}
      ]
    },
  },
  "required": [...]
}

Unfortunately if someone fill the field with spaces it will be valid becouse the space counts as character. That is why I prefer the ajv.addKeyword('isNotEmpty', ...) method, it can uses a trim() function before validate.

Cheers!

Twelfth answered 14/2, 2018 at 22:39 Comment(0)
V
4

Right now there is no built in option in AJV to do so.

Vidar answered 24/11, 2017 at 10:39 Comment(0)
A
3

This can now be achieved using ajv-keywords.
Its a collection of custom schemas which can be used for ajv validator.

Changing schema to

{
  "type": "object",
  "properties": {
    "user_name": {
      "type": "string",
      "allOf": [
        {
          "transform": [
            "trim"
          ]
        },
        {
          "minLength": 1
        }
      ]
    },
   // other properties
  }
}

Using ajv-keywords

const ajv = require('ajv');
const ajvKeywords = require('ajv-keywords');
const ajvInstance = new ajv(options);
ajvKeywords(ajvInstance, ['transform']);

The transform keyword specifies what transformations to be executed before validation.

Aisha answered 18/7, 2020 at 16:49 Comment(0)
C
0

I did the same thing as Ronconi said yet wanted to emphasis on how you can use the schema, for example "not checking the logic".

ajv.addKeyword({
    keyword: 'isNotEmpty',    
    validate: (schema , data) => {
        if (schema){
            return typeof data === 'string' && data.trim() !== ''
        }
        else return true;
    }
});

const schema = {
    type: "object",
    properties: {
        fname: {
            description: "first name of the user",
            type: "string",
            minLength: 3,
            isNotEmpty: false,
        },
}
Captivate answered 3/3, 2022 at 8:47 Comment(0)
C
0

Based on @arthur-ronconi answer, here is another solution that works in Typescript, using the latest version of Ajv (documentation):

import Ajv, { _, KeywordCxt } from "ajv/dist/jtd";

const ajv = new Ajv({ removeAdditional: "all", strictRequired: true });
ajv.addKeyword({
  keyword: 'isNotEmpty',
  schemaType: 'boolean',
  type: 'string',
  code(cxt: KeywordCxt) {
    const {data, schema} = cxt;
    if (schema) {
      cxt.fail(_`${data}.trim() === ''`);
    }
  },
  error: {
    message: 'string field must be non-empty'
  }
});
Cruz answered 25/5, 2022 at 9:14 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.