Rendering of constant property

I am using the Materail React renderer set, I am not using a UI Schema, just data schema. The data Schema has a property that looks like this:

   "inputModelFiles": {
        "oneOf": [
          {
            "title": "Isotropic",
            "type": "object",
            "properties": {
              "anisotropyType": {
                "const": "isotropic"
              },
              "vp": {
                "type": "string",
                "format": "uri"
              }
            },
            "required": [
              "anisotropyType",
              "vp"
            ]
          },
          {
            "title": "TTI",
            "type": "object",
            "properties": {
              "anisotropyType": {
                "const": "tti"
              },
              "vp": {
                "type": "string",
                "format": "uri"
              },
              "epsilon": {
                "type": "string",
                "format": "uri"
              }
            }
            "required": [
              "anisotropyType",
              "vp",
              "epsilon"
            ]
          }
        ]
      }

The UI is rendered correctly with 2 tabs, first tab has one text box called vp, the second has 2 text box one called vp on called epsilon.
The anisotropicType property which is a constant is not rendered which is not a problem as it is redundant with title.
The issue is that the data generated does not include the anisotropicType, which should be set to “isotropic” or “tti” based on which tab you filled in, and the json generated is not compliant with the schema.
Do I need a custom renderer for that? Any guidance on how to create one would be greatly appreciated as I am new to JsonForm.
Thanks!
Cyril

Hi @Cyril-Lagrange ,
JsonForms does not fill in const values automatically as you discovered. This is on purpose.

What you can try to use is using AJV’s capability to fill in default values on validation:

  • Add default entries to your anisotrophyType declarations next to the const like this:
"anisotropyType": {
  "const": "tti",
  "default": "tti"
}
  • Create AJV with useDefaults: true parameter via the createAjv utility from @jsonforms/core, i.e. createAjv({ useDefaults: true }). You should memoize the instance to avoid recreating it on every rerender.
  • Hand the created ajv instance into the root component as a prop.

In case this doesn’t work or you want a custom renderer nontheless, you can find documentation on the JsonForms website on implementing custom renderers here: Custom Renderers - JSON Forms

Best regards,
Lucas

Hi @Cyril-Lagrange
I also just found this issue comment again: [question] Support for const? · Issue #1587 · eclipsesource/jsonforms · GitHub
This also is about const and defaults in oneOf. My solution outlined before might not be sufficient alone. But this comment seems to offer a solution.

Best regards,
Lucas

Thank you @lucas-koehler ! It looks like the use case in the thread you pointed me too is very similar to mind. I will take a look.

Regards
Cyril

The solution in the linked comment is somewhat dangerous: It ties the setting of the const value to UI processing. As a consequence:

  • the data will be shortly out of sync, i.e. a change by JSON Forms without the const value will be reported, followed by an update including the const value
  • the form rerenders and validates multiple times
  • If some “Hide” rule should take affect on the parent, the renderer will not run and the const value will not be set.

However I have very good news for you anyway:
The solution with the default value will work for your case, and that even without adapting AJV.

We recently introduced default support when creating new objects, see here. So when switching tabs, JSON Forms will see the default value and create it immediately, supporting these const use cases neatly.

For this to work you need to use JSON Forms 3.2.0 or later and adapt your schema to use the default as indicated above.