rjsf-team / react-jsonschema-form

A React component for building Web forms from JSON Schema.
https://rjsf-team.github.io/react-jsonschema-form/
Apache License 2.0
13.72k stars 2.15k forks source link

Cannot change property value with liveOmit and omitExtraData for arrays of objects and conditionality #4109

Open anya92 opened 2 months ago

anya92 commented 2 months ago

Prerequisites

What theme are you using?

core

Version

5.x

Current Behavior

I have a problem when trying to change property values using "liveOmit" and "omitExtraData". This is the JSON schema I use:

{
  "title": "Schema",
  "type": "object",
  "properties": {
    "array_of_objects": {
      "title": "Array of Objects",
      "type": "array",
      "items": {
        "$ref": "#/definitions/myArrayOfObjects"
      },
      "minItems": 1
    }
  },
  "definitions": {
    "myArrayOfObjects": {
      "title": "Array Item",
      "type": "object",
      "properties": {
        "name": {
          "title": "Name",
          "type": "string"
        },
        "booleanProperty": {
          "title": "Boolean Property",
          "default": true,
          "type": "boolean"
        }
      },
      "if": {
        "properties": {
          "booleanProperty": {
            "const": true
          }
        }
      },
      "then": {
        "properties": {
          "otherProperty": {
            "title": "Other Property",
            "type": "string",
            "enum": [
              "Hello",
              "World"
            ]
          }
        },
        "required": [
          "otherProperty"
        ]
      },
      "required": [
        "name"
      ]
    }
  }
}

Expected Behavior

It should be possible to change the otherProperty value.

Steps To Reproduce

  1. Go to the rjsf playground
  2. liveOmit and omitExtraData are already turned on, liveValidation is also turned on to see that the condition is valid
  3. try to change value of Other Property - nothing happens

Environment

- OS: macOS 14.2.1
- Node: 18.14.2
- npm: 9.5.0

Anything else?

It works in my project which uses version 5.12.1. But I can't update the package after it stopped working. I already addressed this issue in #3909.

heath-freenome commented 2 months ago

@anya92 It seems like when you turn off omitExtraData everything works fine. This is a duplicate of #2720 (we'll close that one as a duplicate of yours), although your use-case is much clearer. Is this something you are will to try to fix?

anya92 commented 2 months ago

@heath-freenome Thank you for the response. I did notice that turning off omitExtraData resolves the issue, but in my project, it needs to be turned on. Unfortunately, I'm not very familiar with the codebase, so making a quick fix might be challenging for me.

heath-freenome commented 2 months ago

@anya92 I started out not being very familiar with the codebase either. Most of the code you want to look at is in the Form class in @rjsf/core. Feel free to reach out if you have any questions. Thanks

anya92 commented 2 months ago

@heath-freenome I checked the changes in the package and I'm pretty sure my schema stopped working after updating retrieveSchema() in version 5.13.1 and this function started resolving references. In the version I'm currently using, $refs are not resolved.

But even if I manually got rid of $ref and my schema looks like this:

{
  "title": "Schema",
  "type": "object",
  "properties": {
    "array_of_objects": {
      "title": "Array of Objects",
      "type": "object",
      "properties": {
        "name": {
          "title": "Name",
          "type": "string"
        },
        "booleanProperty": {
          "title": "Boolean Property",
          "default": true,
          "type": "boolean"
        }
      },
      "if": {
        "properties": {
          "booleanProperty": {
            "const": true
          }
        }
      },
      "then": {
        "properties": {
          "otherProperty": {
            "title": "Other Property",
            "type": "string",
            "enum": [
              "Hello",
              "World"
            ]
          }
        },
        "required": [
          "otherProperty"
        ]
      }
    }
  }
}

The issue still exists (playground).

You may notice that the if...then section is nested inside array_of_objects. If I move it up, the form will work and the data will not be deleted (playground). But I think this should also work with the above schema because the conditional field is rendered correctly and the validation still throws an error.

Do you have any idea what is causing this behavior and where to fix it?

heath-freenome commented 1 month ago

@anya92 The issue is in the omitExtraData code that is currently in Form. Interestingly someone is working on a PR to pull that code down into the utils library (#4139), maybe you can work with them to see if there is a fix that can be made during the extraction.

helen-m-lin commented 2 weeks ago

Hi @heath-freenome, I'm also having issues with omitExtraData during onSubmit, though not entirely sure if it's the same thing @anya92 is describing. What is the expected behavior? I assumed that it should first omit any extra data in the formData, and then validate the resulting newFormData. Currently I don't think newFormData is being used for validation here. https://github.com/rjsf-team/react-jsonschema-form/blob/e7b82772d4011670dd9f40049b3ba9000431de67/packages/core/src/components/Form.tsx#L709-L712 If needed, I am happy to help out to implement a fix.