Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,17 @@ should change the heading of the (upcoming) version to include a major version b

-->

# 5.22.4

## @rjsf/utils

- Fixed issue with array schema defaults not applying properly when formData is an empty array, fixing [#4335](https://github.com/rjsf-team/react-jsonschema-form/issues/4335).

# 5.22.3

## @rjsf/utils

- Fixed deep nested dependencies issue with assigning values to formData, fixing [[#4334](https://github.com/rjsf-team/react-jsonschema-form/issues/4334)]
- Fixed deep nested dependencies issue with assigning values to formData, fixing [#4334](https://github.com/rjsf-team/react-jsonschema-form/issues/4334)

# 5.22.2

Expand Down
19 changes: 14 additions & 5 deletions packages/utils/src/schema/getDefaultFormState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -432,11 +432,15 @@ export function getArrayDefaults<T = any, S extends StrictRJSFSchema = RJSFSchem
): T | T[] | undefined {
const schema: S = rawSchema;

const neverPopulate = experimental_defaultFormStateBehavior?.arrayMinItems?.populate === 'never';
const ignoreMinItemsFlagSet = experimental_defaultFormStateBehavior?.arrayMinItems?.populate === 'requiredOnly';
const arrayMinItemsStateBehavior = experimental_defaultFormStateBehavior?.arrayMinItems;
const arrayMinItemsPopulate = arrayMinItemsStateBehavior?.populate;
const arrayMergeExtraDefaults = arrayMinItemsStateBehavior?.mergeExtraDefaults;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider doing this?:

Suggested change
const arrayMinItemsStateBehavior = experimental_defaultFormStateBehavior?.arrayMinItems;
const arrayMinItemsPopulate = arrayMinItemsStateBehavior?.populate;
const arrayMergeExtraDefaults = arrayMinItemsStateBehavior?.mergeExtraDefaults;
const { arrayMinItems: arrayMinItemsStateBehavior = {} } = experimental_defaultFormStateBehavior;
const { populate: arrayMinItemsPopulate, mergeExtraDefaults: arrayMergeExtraDefaults } = arrayMinItemsStateBehavior;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not possible to destructure experimental_defaultFormStateBehavior since it can be undefined but I improved it a little.


const neverPopulate = arrayMinItemsPopulate === 'never';
const ignoreMinItemsFlagSet = arrayMinItemsPopulate === 'requiredOnly';
const isPopulateAll = arrayMinItemsPopulate === 'all' || (!neverPopulate && !ignoreMinItemsFlagSet);
const computeSkipPopulate = arrayMinItemsStateBehavior?.computeSkipPopulate ?? (() => false);
const isSkipEmptyDefaults = experimental_defaultFormStateBehavior?.emptyObjectFields === 'skipEmptyDefaults';
const computeSkipPopulate =
experimental_defaultFormStateBehavior?.arrayMinItems?.computeSkipPopulate ?? (() => false);

const emptyDefault = isSkipEmptyDefaults ? undefined : [];

Expand All @@ -460,7 +464,7 @@ export function getArrayDefaults<T = any, S extends StrictRJSFSchema = RJSFSchem
if (neverPopulate) {
defaults = rawFormData;
} else {
defaults = rawFormData.map((item: T, idx: number) => {
const itemDefaults = rawFormData.map((item: T, idx: number) => {
return computeDefaults<T, S, F>(validator, schemaItem, {
rootSchema,
_recurseList,
Expand All @@ -470,6 +474,11 @@ export function getArrayDefaults<T = any, S extends StrictRJSFSchema = RJSFSchem
required,
});
}) as T[];

// If the populate 'requiredOnly' flag is set then we only merge and include extra defaults if they are required.
// Or if populate 'all' is set we merge and include extra defaults.
const mergeExtraDefaults = ((ignoreMinItemsFlagSet && required) || isPopulateAll) && arrayMergeExtraDefaults;
defaults = mergeDefaultsWithFormData(defaults, itemDefaults, mergeExtraDefaults);
}
}

Expand Down
43 changes: 43 additions & 0 deletions packages/utils/test/schema/getDefaultFormStateTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,49 @@ export default function getDefaultFormStateTest(testValidator: TestValidatorType
},
});
});
it('test an array with defaults with no formData', () => {
const schema: RJSFSchema = {
type: 'array',
minItems: 4,
default: ['Raphael', 'Michaelangelo'],
items: {
type: 'string',
default: 'Unknown',
},
};

expect(
computeDefaults(testValidator, schema, {
rootSchema: schema,
includeUndefinedValues: 'excludeObjectChildren',
})
).toEqual(['Raphael', 'Michaelangelo', 'Unknown', 'Unknown']);
});
it('test an array with defaults with empty array as formData', () => {
const schema: RJSFSchema = {
type: 'array',
minItems: 4,
default: ['Raphael', 'Michaelangelo'],
items: {
type: 'string',
default: 'Unknown',
},
};

expect(
computeDefaults(testValidator, schema, {
rootSchema: schema,
rawFormData: [],
includeUndefinedValues: 'excludeObjectChildren',
experimental_defaultFormStateBehavior: {
arrayMinItems: {
mergeExtraDefaults: true,
populate: 'all',
},
},
})
).toEqual(['Raphael', 'Michaelangelo', 'Unknown', 'Unknown']);
});
it('test computeDefaults handles an invalid property schema', () => {
const schema: RJSFSchema = {
type: 'object',
Expand Down