react-jsonschema-form
react-jsonschema-form copied to clipboard
Customize fields to handle null values
Prerequisites
- [x] I have read the documentation;
- [x] In the case of a bug report, I understand that providing a SSCCE example is tremendously useful to the maintainers.
- [x] Ideally, I'm providing a sample JSFiddle or a shared playground link demonstrating the issue.
Description
The JSON schema of the object I defined has a property that be be an array or null. I read the documentation and issues related to the support of the null value, so the "type" for this property in the JSON schema is set as "type": ["array", "null"]. However I have the following error when the value is actually null: TypeError: Cannot read properties of null (reading '0')
Patching the ArrayField.renderFixed array might be an option, but more generally to circumvent this issue I tried and failed to override the ArrayField as documented: if the value if null then display a message "Invalid null value" (using a <pre/> element f.e.), otherwise use the default ArrayField.
const NullableNumberField = function(props) {
if (props.formData == null)
{
return <pre>Invalid value</pre>;
}
return <NumberField {...props}/>;
}
const NullableArrayField = function(props) {
if (props.formData == null)
{
return <pre>Invalid value</pre>;
}
return <ArrayField {...props}/>;
}
const customFields = {NumberField: NullableNumberField, ArrayField: NullableArrayField, ObjectField: NullableObjectField};
form_element =
<Form schema={this.schema}
id={'MyForm'}
idPrefix={this.name.const}
noValidate={true}
formData={this.state.data}
uiSchema={this.uiSchema}
fields={customFields}
...
I still have the same error, and the React components tree is not what I expected; only the NullableObjectField (the top level custom field) is taken into account, any other custom fields are ignored.
Steps to Reproduce
- Implement the code as given in the description
- Set the value property to null
- Render the form.
Expected behavior
I expect that the "Invalid null value" is displayed is the value is actually null, otherwise render the array with the default template.
Actual behavior
Error TypeError: Cannot read properties of null (reading '0')
Version
rjsf/core: 3.2.1 rjsf/bootstrap-4: 3.2.1 react: 17.0.2 react-bootstrap: 1.6.4 react-dom: 17.0.2 react-jsonschema-form: 1.8.1
I'm playing around with the same stuff and still have no solution.
I'm attempting to modify the json schema on the fly to match the actual json value, that is that say: instead of declaring multiple types for a property ["x", "null"], I am setting the type in the schema as "x" if the value is not null and "null" if the value is null. My testing is not comprehensive, still work to be done...
Quite ugly in fact, but might be a workaround?! Suggestions are welcome.
I went through this issue by mainly patching the ArrayField.js in generateKeyedFormData() and renderFixedArray() to create a map based on the schema when the formData is null (no index available). For instance:
function generateKeyedFormData(formData, schema) {
if (formData === null) {
if (typeof schema.items === 'object') {
return [];
}
else if (Array.isArray(schema.items)) {
schema.items.map((item, index) => {
return {
key: generateRowId(),
item: null
};
});
}
else {
console.log('unsupported type', typeof schema.items);
}
}
return !Array.isArray(formData)
? []
: formData.map(item => {
return {
key: generateRowId(),
item,
};
});
}
And
renderFixedArray() {
...
let itemSchemas = [];
if (formData === null) {
items = schema.items.map((item, index) => null);
itemSchemas = schema.items.map((item, index) => item);
}
else {
itemSchemas = schema.items.map((item, index) =>
retrieveSchema(item, rootSchema, formData[index])
);
}
Some more tweaks are spread through the code (ObjectField, I won't share here, unless I get some help to merge the code since I am a newbie in the github world for code management!
With the v5 beta, maybe this is fixed, otherwise I'm open to helping you write a fix
Hi Heath,
I will give a try to the v5 beta version; I'll come back to you within a few days. Thanks for your kind proposition.
@moulinfr how did you patch it? we're in similar trouble, and i'm finding no way for a null
(ideally would be undefined
) default value to be respected for array fields that can be included or left out.
A very hackishly hacky hack: added oneOf: []
to the properties, so that computeDefaults()
is tricked into letting undefined
as the value; still not perfect as now ArrayField
's constructor ignores it and puts []
in its place 🙃 (const { formData = [] } = props;
) but it gets us closer