formData contains extra properties in react-jsonschema-form

26 Views Asked by At

I was learning React JSON Schema Form and was practicing here. In the If Then Else section I found something weird (that was also happening to my form).

Below is the JSONSchema:

{
  "type": "object",
  "properties": {
    "animal": {
      "enum": [
        "Cat",
        "Fish"
      ]
    }
  },
  "allOf": [
    {
      "if": {
        "properties": {
          "animal": {
            "const": "Cat"
          }
        }
      },
      "then": {
        "properties": {
          "food": {
            "type": "string",
            "enum": [
              "meat",
              "grass",
              "fish"
            ]
          }
        },
        "required": [
          "food"
        ]
      }
    },
    {
      "if": {
        "properties": {
          "animal": {
            "const": "Fish"
          }
        }
      },
      "then": {
        "properties": {
          "food": {
            "type": "string",
            "enum": [
              "insect",
              "worms"
            ]
          },
          "water": {
            "type": "string",
            "enum": [
              "lake",
              "sea"
            ]
          }
        },
        "required": [
          "food",
          "water"
        ]
      }
    },
    {
      "required": [
        "animal"
      ]
    }
  ]
}

Now when I selected the type as 'fish', it rendered two fields as expected and the formData also looks good after selecting the corresponding values.

Form Data:

{
  "animal": "Fish",
  "food": "insect",
  "water": "sea"
}

But when I switch the type to cat, the UI renders the correct field (food) and upon selecting a value for food, the formData still contains the water field.

New Form Data:

{
  "animal": "Cat",
  "food": "grass",
  "water": "sea"
}

Although the UI is correct but why the formData have this extra field which is a result of previous selection?

I want to render a form at the frontend and require this formData as a payload to send request on the server. But as this contains these extra fields (which is a result of previous selections), it is causing problems.

In my use case, the form is very complex with a lot of conditionals so it is bound to be filled this way (reselecting some fields). And these extra properties is causing issues.

Is there any way to remove these extra properties from formData and keep only those properties that satisfies the JSONSchema?

Or if that's not impossible, how can I write a parser that takes JSONSchema and formData as input and generates the formData that is clean (only have the fields that should be present)?

1

There are 1 best solutions below

0
audrynyonata On

Are you trying to remove some properties from a JSON object?

const formData = {
  "animal": "Cat",
  "food": "grass",
  "water": "sea"
}
// Option 1: use object destructuring
const { animal, food, ...rest } = formData;

const newFormData = {
  animal: animal,
  food: food
} // {animal: 'Cat', food: 'grass'}

console.log(rest) // {water: 'sea'}
// Option 2: build new object using forEach
const fields = {
  cat: ['animal', 'food'],
  fish: ['animal', 'food', 'water']
}

const { animal } = formData;
const selectedFields = fields[animal]; 

const newFormData = {};
selectedFields.forEach(field => {
  newFormData[field] = formData[field];
});

console.log(newFormData); // {animal: 'Cat', food: 'grass'}