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
14.38k stars 2.2k forks source link

Default values don't trigger dependencies #1703

Open sampsonbryce opened 4 years ago

sampsonbryce commented 4 years ago

Prerequisites

Description

I have a schema with two dependencies, one nested inside the other. I have default values for all of my attributes such that the whole form should be immediately populated once the topmost checkbox is checked. However, default values are only populated as deep as the first dependency.

Steps to Reproduce

  1. Go to playground
  2. Check the Enabled? box
  3. Notice filter_type is populated with its default value, but filters is not shown and therefore has no value. In other words, the default value of filter_type does not trigger the showing of the filters dependency.
  4. Change filter_type to custom and then back to expression. You'll see that now the filters field shows properly with its default value.

Expected behavior

Because filters is conditionally shown based on the value of filter_type, I would expect that the default value I have set for filter_type would trigger showing filters.

Actual behavior

Even though filter_type has a value that should trigger its dependencies, because its value is initially set via a default value, those dependencies are not triggered by the default value.

Version

1.8.1 or whatever the playground is running

Initial Investigation

What I believe the issue to be is, because the getDefaultFormState is only called once in the Form component (link), the first layer of dependencies is triggered and defaults are returned in the formData parameter for the first layer. However, because the second and deeper layers of nested data are dependent on the previous layer being populated with defaults, they are not triggered.

E.g. In my playground example when enabled is set to true it means the default state can be inferred for filter_type since it is dependent on enabled and enabled is provided as existing inputFormData to getDefaultFormState. However, since filters is dependent on filter_type and since filter_type is not provided in inputFormData the dependencies are not triggered.

To solve this, getDefaultFormState needs to be called more that once until all dependencies have been triggered by all default values. A rudimentary way of accomplishing this would seem to be looping over getDefaultFormState with the output of the previous call being the inputFormData of the next until a deep equals comparison shows that the inputFormData and output formData are equivalent. Although this is likely not the smartest way to solve the problem.

Molinsharian commented 4 years ago

I have the same problem. You have a solution in your code?

sampsonbryce commented 4 years ago

This issue seems to come from the fact that when traversing down the schema tree and populating defaults, if a default key is found it is prioritized over recursing again.

https://github.com/rjsf-team/react-jsonschema-form/blob/master/packages/core/src/utils.js#L171

This line of code checking for the defaults key seems to go against the comment in that function

// Compute the defaults recursively: give highest priority to deepest nodes.

By returning so early if a default key is found, we don't traverse to the deepest nodes in the tree first. I would changing the order of execution of the function to check for the default key after all recursion has occurred if the intended behavior is to actually go to the deepest nodes first.

Feel free to close this for now though. The issue appears to be resolved by only setting default nodes on fields that are leaves in the schema tree. This can be exemplified in a modified version of the playground listed in the issue description. new playground

rheafernandes commented 3 years ago

Hi facing the same issue, has this been fixed yet? Could someone help me with a workaround?

sampsonbryce commented 3 years ago

@rheafernandes do you have a playground link for your problem?

lucaswiman commented 2 years ago

It looks like @sampsonbryce's playground link is working now. Is this still valid?