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

Dependency defaults do not render for uncontrolled Form components #1316

Closed
3 tasks done
MatinF opened this issue Jun 8, 2019 · 20 comments · Fixed by #1371
Closed
3 tasks done

Dependency defaults do not render for uncontrolled Form components #1316

MatinF opened this issue Jun 8, 2019 · 20 comments · Fixed by #1371
Labels

Comments

@MatinF
Copy link

MatinF commented Jun 8, 2019

Prerequisites

Description

With release 1.6.1, some of our dependency defaults now render correctly - incl. the ones listed in a previous issue. However, we still have one set of dependency defaults that do not render. My hypothesis is that it may be because we also use "definitions" as part of the structure.

Steps to Reproduce

I will provide a playground example of the issue - but the playground seems to be 1.6.0 rather than 1.6.1, so currently I can't create one. However, I've added the example Schema below. Note that the option C is the one that has default values that do not get inserted.

{
  "type": "object",
  "definitions": {
    "can": {
      "type": "object",
      "properties": {
        "phy": {
          "title": "TitleX",
          "type": "object",
          "properties": {
            "bit_rate_cfg_mode": {
              "title": "TitleY",
              "type": "integer",
              "default": 0,
              "anyOf": [
                {
                  "title": "A",
                  "enum": [
                    0
                  ]
                },
                {
                  "title": "B",
                  "enum": [
                    1
                  ]
                },
                {
                  "title": "C",
                  "enum": [
                    2
                  ]
                }
              ]
            }
          },
          "dependencies": {
            "bit_rate_cfg_mode": {
              "oneOf": [
                {
                  "properties": {
                    "bit_rate_cfg_mode": {
                      "enum": [
                        0
                      ]
                    }
                  }
                },
                {
                  "properties": {
                    "bit_rate_cfg_mode": {
                      "enum": [
                        1
                      ]
                    }
                  }
                },
                {
                  "properties": {
                    "bit_rate_cfg_mode": {
                      "enum": [
                        2
                      ]
                    },
                    "brp": {
                      "title": "XYZ 1",
                      "type": "integer",
                      "default": 12,
                      "minimum": 1
                    }
                  }
                }
              ]
            }
          }
        }
      }
    }
  },
  "properties": {
    "can_1": {
      "title": "CHANNEL 1",
      "$ref": "#/definitions/can"
    }
  }
}
@epicfaace
Copy link
Member

@MatinF Playground has been updated to 1.6.1 -- here is the playground link for the aforementioned schema. Everything seems to be working fine?

@MatinF
Copy link
Author

MatinF commented Jun 10, 2019

@epicfaace Thanks for updating it. I agree that the sample - and also my full Schema - runs fine in the playground. It's really strange why it does not run correctly in my project as I'm running 1.6.1 - but I guess I'll have to try and dig a bit deeper to see if I can replicate the issue somewhere beyond the playground.

Thanks for your help,
Martin

@MatinF
Copy link
Author

MatinF commented Jun 10, 2019

After some more tests, I can see that it does indeed work - but for some reason the default values were not visible until I submit the updated formData. I.e. it would not show up in my editor - but that may be something related to my state handling. I'm closing this.

@MatinF MatinF closed this as completed Jun 10, 2019
@MatinF
Copy link
Author

MatinF commented Jun 10, 2019

Just one comment on this: I've tested around and I can't seem to find any obvious issue in my implementation of the react-jsonschema-form.

Perhaps an issue can be that if the formData is not updated by user input directly - but by an indirect change (e.g. as in dependent default fields) - it breaks the state update functionality in some implementations.

I run state updates by providing the following form input:

onChange={this.handleChange}

Where handleChange is as below:

handleChange = ({ formData }) => {}

It seems like this function is correctly triggered everytime a field is changed. When I select a field in a dropdown that provides additional sub fields (as in the playground example), this also leads to a triggering of this function. However, it does not create the new default values immediately. I use a pagination plugin - and when I change tab, it updates the formData state correctly and the default values are shown. Without the pagination plugin, I have to hit submit in order for the form to get updated - which means users will in reality enter submit data that they've not seen in the form.

I'll dig deeper on my end, but it may be others have implemented this the same way as I have and hence encounter this issue.

@MatinF
Copy link
Author

MatinF commented Jun 11, 2019

@epicfaace: I've tested the issue of rendering dependency defaults some more.

It's correct that the examples mentioned work in the Playground - and as such I'm unable to replicate the issue there. However, when I create a very basic app (using create-react-app) I find the following issue with dependency defaults:

  1. The dependent default value does not render in the dropdown example when option C is selected
  2. Further, when submit is pressed, the default value is not included in the submitted output (see console)

Replication steps

  1. Use "create-react-app [app-name]" to create a new basic app
  2. In the app, install react-jsonschema-form via "npm install react-jsonschema-form"
  3. Copy the JSON Schema from the original post into a "schema.json" and add it "src" folder
  4. In the "index.js" file, replace the content with the below code:
import React, { Component } from "react";
import { render } from "react-dom";
import schemaJson from "./schema.json";
import Form from "react-jsonschema-form";

const onSubmit = ({formData}, e) => console.log("Data submitted: ",  formData);

render((
  <Form schema={schemaJson}
        onSubmit={onSubmit}
        />
), document.getElementById("root"));

This results in a basic (unformatted) example of the editor, in which it should be evident what my issue relates to. Note that the above sample is meant to mimic very closely the guidance from the installation docs.

My hypothesis is that the Playground "fixes" the root cause issue behind this via some form of state update occurring behind-the-scenes - and which may not necessarily occur in more bare-bones apps.

I hope the above helps to reproduce the issue I'm seeing in my production app. Happy to hear your thoughts and whether I've missed something.

Thank you,
Martin

@MatinF MatinF reopened this Jun 11, 2019
@epicfaace
Copy link
Member

Yes, you're right -- here's a jsfiddle reproduction: https://jsfiddle.net/h0adfqjy/

@epicfaace epicfaace added the bug label Jun 12, 2019
@khelkun
Copy link

khelkun commented Jun 13, 2019

Is the only workaround for the moment is to provide a right formData property at the Form component rendering?

@MatinF
Copy link
Author

MatinF commented Jun 14, 2019

I've not been able to find a stable work-around on my end (but of course happy to hear there are suggestions). Would be great if this could be resolved within the module

@epicfaace
Copy link
Member

I actually ran into this issue in another application using rjsf (my schema was a oneOf with a bunch of constant objects) and my workaround was just to modify the schema on the fly to make the schema for the default value the first item in oneOf. This worked in my specific case but probably won't work in all cases...

@MatinF
Copy link
Author

MatinF commented Jun 15, 2019

@epicfaace Our challenge with such a solution is that we need to have a specific value in the dropdown be the default selection of the dropdown. However, one of the non-default dropdown selections have dependency defaults - hence we run into the rendering issue.

Since this seems to work in the playground, I guess there's some sort of compensation fix going on in that code. Perhaps a similar thinking could be used to solve this issue. I use the pagination extension to rjsf and noticed that when I select the "option C" in the dropdown example, the default value will be populated when I switch tabs back and forth. So I'd assume some form of similar effect could be triggered as a special case in rjsf when dependency defaults need to be rendered.

Best,

@epicfaace
Copy link
Member

This is strange -- even the example originally mentioned in #1293 is not working outside of the playground: https://jsfiddle.net/3e18wkd5/

@MatinF
Copy link
Author

MatinF commented Jun 19, 2019

That's also what I've found in my production build. The dangerous aspect is that when using release 1.6.1, the defaults will be populated in unexpected settings. The result can be that users see one thing in the form (unpopulated defaults) - yet when they submit, the defaults are populated in some cases.

This would be a really great thing to get resolved in a new release - or alternatively to have some workaround that's not too hacky.

@epicfaace
Copy link
Member

It seems like the workaround is to make the form a controlled component -- i.e., save the form data in the state and update it in during onChange -- see this jsfiddle for example: https://jsfiddle.net/qrhws8f6/

@MatinF
Copy link
Author

MatinF commented Jun 21, 2019

I managed to create a slightly "hacky" workaround. In my case, the setup is a bit more complex as I need to load the formData as an external input via state from a redux store. If the user chooses a new formData starting point from a dropdown, the formData needs to be populated with this - yet at the same time, I need it to correctly render.

The solution was to add a dispatch that updates the state from handleChange. Effectively, it renders the form twice on every change, which is a bit hacky, but not really noticeable in practice. If a formal solution comes up in a future release, I'd be interested in knowing - closing this for now.

@MatinF MatinF closed this as completed Jun 21, 2019
@epicfaace
Copy link
Member

Yeah, good you found a solution, although I think this is still a problem worth fixing.

@epicfaace epicfaace reopened this Jun 21, 2019
@epicfaace epicfaace changed the title Release 1.6.1: Some dependency defaults are still not rendering Dependency defaults do not render for uncontrolled Form components Jun 21, 2019
@MatinF
Copy link
Author

MatinF commented Jun 21, 2019

Agreed, would be great with a non hacky solution

@MatinF
Copy link
Author

MatinF commented Jul 18, 2019

Just wanted to check if there are any plans to cover this in a future release, or if we should try to attempt some work-around ourselves? Thanks!

@OleksiL
Copy link

OleksiL commented Jul 23, 2019

I have the same issue.
When I create two dependencies for dropdown options with each having a default value, these default values don't render at the first selection of the option. But if I switch between options back and forward - they start rendering defaults in their dependencies.

Using Form as a controlled component didn't help me.
Hope to see a fix soon.

Thanks,
Oleksii

@epicfaace
Copy link
Member

@MatinF hopefully this will be fixed soon, it just requires some time to debug and see what exactly the problem is. Contributions welcome!

@epicfaace
Copy link
Member

@OleksiL can you make a new issue for that and link to a playground reproduction in it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants