Skip to content

Commit f5c98f3

Browse files
committed
Fixed issue with assigning values to deeply nested required properties
1 parent 433f99b commit f5c98f3

File tree

3 files changed

+55
-6
lines changed

3 files changed

+55
-6
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ should change the heading of the (upcoming) version to include a major version b
1616
1717
-->
1818

19+
# 5.24.0
20+
21+
## @rjsf/utils
22+
23+
- Fixed issue with assigning default values to formData with deeply nested required properties, fixing [#4399](https://github.com/rjsf-team/react-jsonschema-form/issues/4399)
24+
1925
# 5.23.2
2026

2127
## @rjsf/core

packages/utils/src/schema/getDefaultFormState.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -115,11 +115,11 @@ function maybeAddDefaultToObject<T = any>(
115115
// Or if the schema has a const property defined, then we should always return the computedDefault since it's coming from the const.
116116
obj[key] = computedDefault;
117117
} else if (emptyObjectFields !== 'skipDefaults') {
118-
if (isObject(computedDefault)) {
119-
// If isParentRequired is undefined, then we are at the root level of the schema so defer to the requiredness of
120-
// the field key itself in the `requiredField` list
121-
const isSelfOrParentRequired = isParentRequired === undefined ? requiredFields.includes(key) : isParentRequired;
118+
// If isParentRequired is undefined, then we are at the root level of the schema so defer to the requiredness of
119+
// the field key itself in the `requiredField` list
120+
const isSelfOrParentRequired = isParentRequired === undefined ? requiredFields.includes(key) : isParentRequired;
122121

122+
if (isObject(computedDefault)) {
123123
// If emptyObjectFields 'skipEmptyDefaults' store computedDefault if it's a non-empty object(e.g. not {})
124124
if (emptyObjectFields === 'skipEmptyDefaults') {
125125
if (!isEmpty(computedDefault)) {
@@ -138,11 +138,12 @@ function maybeAddDefaultToObject<T = any>(
138138
} else if (
139139
// Store computedDefault if it's a defined primitive (e.g., true) and satisfies certain conditions
140140
// Condition 1: computedDefault is not undefined
141-
// Condition 2: If emptyObjectFields is 'populateAllDefaults' or 'skipEmptyDefaults) or if the key is a required field
141+
// Condition 2: If emptyObjectFields is 'populateAllDefaults' or 'skipEmptyDefaults)
142+
// Or if isSelfOrParentRequired is 'true' and the key is a required field
142143
computedDefault !== undefined &&
143144
(emptyObjectFields === 'populateAllDefaults' ||
144145
emptyObjectFields === 'skipEmptyDefaults' ||
145-
requiredFields.includes(key))
146+
(isSelfOrParentRequired && requiredFields.includes(key)))
146147
) {
147148
obj[key] = computedDefault;
148149
}

packages/utils/test/schema/getDefaultFormStateTest.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2284,6 +2284,48 @@ export default function getDefaultFormStateTest(testValidator: TestValidatorType
22842284
})
22852285
).toEqual({ requiredProperty: 'foo' });
22862286
});
2287+
it('test an object with a required property that has a nested optional property which has a nested required property with default', () => {
2288+
const schema: RJSFSchema = {
2289+
type: 'object',
2290+
properties: {
2291+
baseRequiredProperty: {
2292+
type: 'object',
2293+
properties: {
2294+
optionalProperty: {
2295+
type: 'object',
2296+
properties: {
2297+
nestedRequiredProperty: {
2298+
type: 'string',
2299+
default: '',
2300+
},
2301+
},
2302+
required: ['nestedRequiredProperty'],
2303+
},
2304+
requiredProperty: {
2305+
type: 'string',
2306+
default: 'foo',
2307+
},
2308+
},
2309+
required: ['requiredProperty'],
2310+
},
2311+
baseOptionalProperty: {
2312+
type: 'string',
2313+
default: 'baseOptionalProperty',
2314+
},
2315+
},
2316+
required: ['baseRequiredProperty'],
2317+
};
2318+
expect(
2319+
computeDefaults(testValidator, schema, {
2320+
rootSchema: schema,
2321+
experimental_defaultFormStateBehavior: { emptyObjectFields: 'populateRequiredDefaults' },
2322+
})
2323+
).toEqual({
2324+
baseRequiredProperty: {
2325+
requiredProperty: 'foo',
2326+
},
2327+
});
2328+
});
22872329
it('test an object with an optional property that has a nested required property and includeUndefinedValues', () => {
22882330
const schema: RJSFSchema = {
22892331
type: 'object',

0 commit comments

Comments
 (0)