Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

For arrays, don't assign a default value of an empty array. #3880

Closed
1 task done
abdalla-rko opened this issue Sep 25, 2023 · 4 comments
Closed
1 task done

For arrays, don't assign a default value of an empty array. #3880

abdalla-rko opened this issue Sep 25, 2023 · 4 comments

Comments

@abdalla-rko
Copy link
Contributor

Prerequisites

What theme are you using?

core

Is your feature request related to a problem? Please describe.

When you have a multiSelect/array field, by default an empty array will be assigned to the array field in the formData. If we try to submit a required empty multiSelect, the form will be submitted because AJV8 doesn't recognize it as empty and doesn't show validation errors. To avoid this behavior, we can currently set the emptyObjectFields to skipDefault, but this will skip all default values in the schema for example also for a string input that has default property.

Demonstration of the issue:

{
  "type": "object",
  "required": [
    "requiredMultiSelect",
    "requiredStringInput"
  ],
  "properties": {
    "multiSelect": {
      "type": "array",
      "title": "Multiple Select Input",
      "items": {
        "type": "string",
        "enum": [
          "option1",
          "option2"
        ]
      },
      "uniqueItems": true
    },
    "requiredMultiSelect": {
      "type": "array",
      "title": "Required multiple Select Input",
      "items": {
        "type": "string",
        "enum": [
          "option1",
          "option2"
        ]
      },
      "uniqueItems": true
    },
    "stringInput": {
      "type": "string",
      "default": "Hello"
    },
    "requiredStringInput": {
      "type": "string",
      "default": "Hello"
    }
  }
}

The formData results from different options of emptyObjectFields (Demo link).

  1. populateAllDefaults (Legacy):
{
  "multiSelect": [],
  "requiredMultiSelect": [],
  "stringInput": "Hello",
  "requiredStringInput": "Hello"
}

Raw Validate response: no AJV errors encountered.

  1. populateRequiredDefaults.
{
  "requiredMultiSelect": [],
  "requiredStringInput": "Hello"
}

Raw Validate response: no AJV errors encountered.

  1. skipDefaults
{}

Raw Validate response:

{
  "errors": [
    {
      "instancePath": "",
      "schemaPath": "#/required",
      "keyword": "required",
      "params": {
        "missingProperty": "requiredMultiSelect"
      },
      "message": "must have required property 'requiredMultiSelect'",
      "schema": [
        "requiredMultiSelect",
        "requiredStringInput"
      ],
      "parentSchema": {
        "type": "object",
        "required": [
          "requiredMultiSelect",
          "requiredStringInput"
        ],
        "properties": {
          "multiSelect": {
            "type": "array",
            "title": "Multiple Select Input",
            "items": {
              "type": "string",
              "enum": [
                "option1",
                "option2"
              ]
            },
            "uniqueItems": true
          },
          "requiredMultiSelect": {
            "type": "array",
            "title": "Required multiple Select Input",
            "items": {
              "type": "string",
              "enum": [
                "option1",
                "option2"
              ]
            },
            "uniqueItems": true
          },
          "stringInput": {
            "type": "string",
            "default": "Hello"
          },
          "requiredStringInput": {
            "type": "string",
            "default": "Hello"
          }
        }
      },
      "data": {}
    },
    {
      "instancePath": "",
      "schemaPath": "#/required",
      "keyword": "required",
      "params": {
        "missingProperty": "requiredStringInput"
      },
      "message": "must have required property 'requiredStringInput'",
      "schema": [
        "requiredMultiSelect",
        "requiredStringInput"
      ],
      "parentSchema": {
        "type": "object",
        "required": [
          "requiredMultiSelect",
          "requiredStringInput"
        ],
        "properties": {
          "multiSelect": {
            "type": "array",
            "title": "Multiple Select Input",
            "items": {
              "type": "string",
              "enum": [
                "option1",
                "option2"
              ]
            },
            "uniqueItems": true
          },
          "requiredMultiSelect": {
            "type": "array",
            "title": "Required multiple Select Input",
            "items": {
              "type": "string",
              "enum": [
                "option1",
                "option2"
              ]
            },
            "uniqueItems": true
          },
          "stringInput": {
            "type": "string",
            "default": "Hello"
          },
          "requiredStringInput": {
            "type": "string",
            "default": "Hello"
          }
        }
      },
      "data": {}
    }
  ]
}
  1. What I would like to get:
{
  "stringInput": "Hello",
  "requiredStringInput": "Hello"
}

Describe the solution you'd like

Introduce a new option for emptyObjectFields. For example skipEmptyDefaults, which will not assign an empty array to an array/multiSelect field. It will still apply the default value if we have a default property present in your schema.

<Form 
  experimental_defaultFormStateBehavior={{
    emptyObjectFields: "skipEmptyDefaults"
}}
/>

What do you think about this?

Describe alternatives you've considered

No response

@abdalla-rko abdalla-rko added feature Is a feature request needs triage Initial label given, to be assigned correct labels and assigned labels Sep 25, 2023
@jlitze-icims
Copy link

I'm seeing the same thing and would love a "skipEmptyDefaults" option

@heath-freenome
Copy link
Member

@abdalla-rko This sounds like a great new experimental feature. Are you willing to build it?

@heath-freenome heath-freenome added help wanted arrays defaults and removed needs triage Initial label given, to be assigned correct labels and assigned labels Oct 6, 2023
@abdalla-rko
Copy link
Contributor Author

Hi @heath-freenome, sure!

@heath-freenome
Copy link
Member

@abdalla-rko Awesome, do reach out if you have any questions or need help

heath-freenome pushed a commit that referenced this issue Feb 21, 2024
* Added skipEmptyDefaults feature

* Fixed an issue where the skipEmptyDefault option was not displaying default values for fields that are not required.

* Updated tests and the changelog

* Updated changelog: moved chakra-ui changes above utils.

---------

Co-authored-by: Abdallah Al-Soqatri <abdallah.al-soqatri@aspentech.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants