JsonForms not showing errors for required object with required properties in it for empty data

Dear JSONForms Team,
I have a problem with showing errors for nested objects.

JSON Schema:

{ 
  "type": "object", 
  "properties": { 
    "person": { 
      "type": "object", 
      "properties": { 
        "firstName": { "type": "string" }, 
        "lastName": { "type": "string" } 
      }, 
      "required": ["firstName", "lastName"] 
    } 
  }, 
  "required": ["person"] 
} 

UI Schema:

{ 
  "type": "VerticalLayout", 
  "elements": [ 
    { 
      "type": "Control", 
      "properties": "#/properties/person/properties/firstName" 
    }, 
    { 
      "type": "Control", 
      "properties": "#/properties/person/properties/lastName" 
    } 
  ] 
} 

Example initial data: Empty {}

Problem: AJV properly returns the error “person must be required.” However, JsonForms does not render the error because there is no UI element with this scope. As a result, the button to submit the form is disabled, but no errors are shown.

How is it possible to automatically detect such errors and propagate them to nested object properties?

The idea is to detect for each “scope”: if AJV “keyword” is “required”, and AJV “instancePath” is any parent object of the “scope” at any level, and the data object where “scope” resides does not exist, and JSON Schema includes “scope” in “required”, then the AJV error belongs to this “scope”.

Thank you!

1 Like

Hi @Anton,

Each renderer has full access to the full JSON Forms state (via useJsonForms()). Therefore, each renderer can show arbitrary errors.

In your case you can use custom renderers which not only check “their” errors, but also show parent errors.

However this will be a rather unintuitive UI, as “person is required” is not a sensible message for the firstName and lastName fields.

What we usually do for these intermediate objects which are not controllable via the UI directly, is to define an empty default value for them, e.g.

{ 
  "type": "object",
  "default": {},
  "properties": { 
    "person": { 
      "type": "object", 
      "properties": { 
        "firstName": { "type": "string" }, 
        "lastName": { "type": "string" } 
      }, 
      "required": ["firstName", "lastName"] 
    } 
  }, 
  "required": ["person"] 
} 

Then, by enabling default support, you will not encounter the person is required error anymore.

2 Likes

Hi @sdirix ,
Thank you for the help!