2
votes

I would like to validate a schema based on either its maximum/minimum (number) OR maximumLength/minimumLength (string). I have a json form:

[
  {
    "key":"foo",  
    "title":"Test",
    "type":"string" 
  }
]

and a json schema:

    {
 "type": "object",
  "properties": {
    "foo": {
        "type": ["number","string"],
        "maxLength":2,
        "minLength":0,
        "minimum":3,
        "maximum":10
    }
  }
}

and a json model:

{
  "foo": "bar"
}

Why does this example not work with validation? The model I have is not validated to false. According to this document it is possible to have different types defined in an array, but how can we do validation based on min/max values?

3

3 Answers

2
votes

Your schema is correct. The validator you are using doesn't work properly. Here is an alternative that uses anyOf instead.

{
    "type": "object",
    "properties": {
        "foo": {
            "anyOf": [
                { "$ref": "#/definitions/boundedNumber" }
                { "$ref": "#/definitions/boundedString" }
            ]
        }
    },
    "definitions": {
        "boundedString": {
            "type": "string",
            "maxLength": 2,
            "minLength": 0
        },
        "boundedNumber": {
            "type": "number",
            "minimum": 3,
            "maximum": 10
        }
    }
}

Although it is quite a bit longer, some would argue that this is actually easier to read/maintain because of the separation of the type specific keywords.

1
votes

Your schema is validating JSON objects ("type":"object"). In addition, if they have a property with key "foo", its value must be either a number between 3 an 10, or a string of maximum length 2.

Valid objects according to your schema:

{"foo":6}
{"foo":"as"}

Invalid objects:

{"foo":60}
{"foo":"asereje"}

If you want to validate arrays you must define your parent object as an array and use items tag to specify the schema for the array items, for instance:

{
    "type" : "array",
    "items" : {
        "type" : "object",
        "properties" : {
            "foo" : {
                "type" : ["number", "string"],
                "maxLength" : 2,
                "minLength" : 0,
                "minimum" : 3,
                "maximum" : 10
            }
        }
    }
}

The schema above would validate the following JSON array:

[{
        "foo" : 6
    }, {
        "foo" : "as"
    }
]
0
votes

John the issue is the type "type" : ["number", "string"]

Angular Schema Form is generating fields from the combined JSON Schema and the UI Schema (form), when the field type is defined it knows which type to validate against, when there are multiple types it doesn't know which part of the spec to base the form field against, so it falls back to a textbox and does not add the appropriate validation requirements for string alone.

To achieve your desired outcome you would need to tell it which field type you wish to use. There is a bug in the 0.8.x versions where it does not validate based on the type set in the UI schema if it cannot determine the type in the data schema, I believe that is fixed in the latest development branch. If not if there is an issue raised in Git, I would prioritise it.