anyOf not working as wrapper for if/then

I’m trying to do a multi-conditional required array. It works when I use allOf but of course that means all of my conditions need to be met. Rather, I need certain conditions to be met for certain fields. I do not want to make a custom renderer because this ought to be table-stakes.

"anyOf": [
                    {
                        "if": {
                            "properties": {
                                "veteran": {
                                    "const": true
                                }
                            }
                        },
                        "then": {
                            "required": [
                                "veteran_unemployed"
                            ]
                        }
                    },
                    {
                        "if": {
                            "properties": {
                                "snap": {
                                    "const": true
                                }
                            }
                        },
                        "then": {
                            "required": [
                                "snap_benefits_extras_name",
                                "snap_benefits_before",
                                "snap_benefits_extras_city_state"
                            ]
                        }
                    }
                ]

Hi @roblesterjr,

Can you explain what the issue is exactly? An allOf over if entries does not require all of the if to be true.

In my testing, it did. Fields specified in the then result were not required until both if conditions evaluated to true.

allOf is what you want to apply all restrictions. It does not mean that all of the ifs need to be true for the then to apply.

You can easily test this with online JSON Schema validators like this one.

Here you can see it applied in JSON Forms

Using this schema

{
  "type": "object",
  "properties": {
    "veteran": {
      "type": "boolean"
    },
    "veteran_unemployed": {
      "type": "boolean"
    },
    "snap": {
      "type": "boolean"
    },
    "snap_benefits_extras_name": {
      "type": "string"
    },
    "snap_benefits_before": {
      "type": "boolean"
    },
    "snap_benefits_extras_city_state": {
      "type": "string"
    }
  },
  "allOf": [
    {
      "if": {
        "properties": {
          "veteran": {
            "const": true
          }
        },
        "required": ["veteran"]
      },
      "then": {
        "required": ["veteran_unemployed"]
      }
    },
    {
      "if": {
        "properties": {
          "snap": {
            "const": true
          }
        },
        "required": ["snap"]
      },
      "then": {
        "required": [
          "snap_benefits_extras_name",
          "snap_benefits_before",
          "snap_benefits_extras_city_state"
        ]
      }
    }
  ]
}

and this UI Schema

{
  "type": "VerticalLayout",
  "elements": [
    {
      "type": "Control",
      "scope": "#/properties/veteran"
    },
    {
      "type": "Control",
      "scope": "#/properties/veteran_unemployed"
    },
    {
      "type": "Control",
      "scope": "#/properties/snap"
    },
    {
      "type": "Control",
      "scope": "#/properties/snap_benefits_extras_name"
    },
    {
      "type": "Control",
      "scope": "#/properties/snap_benefits_before"
    },
    {
      "type": "Control",
      "scope": "#/properties/snap_benefits_extras_city_state"
    }
  ]
}

then this is the result

AllOfRequired