Search code examples
javascriptajv

Why isn't $data reference working in this example?


I have set the $data option to true, and am trying to limit endDate to be at least the value of the startDate using a $data expression. This example should fail validation, but it does not. :(

var Ajv = require('ajv');
var ajv = new Ajv({allErrors: true, $data: true});

var schema = {
  "properties": {
    "filter": { "properties": {
        "startDate": { type: 'string', format:'date'},
        "endDate": { type: 'string', format:'date', formatMinimum: {'$data': '/filter/startDate'}}
  }}
}};

var validate = ajv.compile(schema);

test({filter: {startDate:'2008-09-01', endDate: '2004-09-01'}});

function test(data) {
  var valid = validate(data);
  if (valid) console.log('Valid!');
  else console.log('Invalid: ' + ajv.errorsText(validate.errors));
}

I have tried various JSON pointers.. 0/startDate 1/startDate and the shown /filter/startDate and all of them result in the same Valid! response.

I expect an Invalid response with a message about endDate needing a minimum of the startDate, but I'm getting a Valid! response.

You can see a running example at https://runkit.com/jcdietrich/5d0a45ced5afb8001c33808b


Solution

  • formatMinimum is not supported by the base ajv package. ajv-keywords is required.

    var Ajv = require('ajv');
    var ajv = new Ajv({allErrors: true, $data: true});
    require("ajv-keywords")(ajv)
    
    var schema = {
      "properties": {
        "filter": { "properties": {
            "startDate": { type: 'string', format:'date'},
            "endDate": { type: 'string', format:'date', formatMinimum: {'$data': '/filter/startDate'}}
      }}
    }};
    
    var validate = ajv.compile(schema);
    
    test({filter: {startDate:'2008-09-01', endDate: '2004-09-01'}});
    
    function test(data) {
      var valid = validate(data);
      if (valid) console.log('Valid!');
      else console.log('Invalid: ' + ajv.errorsText(validate.errors));
    }