From 4ef37568b485b412b0bb6523fbabbc9bf1db7df0 Mon Sep 17 00:00:00 2001 From: vlack Date: Wed, 26 Oct 2022 20:34:41 +0300 Subject: [PATCH] fix omit field names with dot #2643 (#3203) * fix omit field names with dot #2643 * add type casting Co-authored-by: Heath C <51679588+heath-freenome@users.noreply.github.com> --- CHANGELOG.md | 1 + packages/core/src/components/Form.tsx | 17 ++++++++++------- packages/core/test/Form_test.js | 22 +++++++++++----------- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b3761884c..f823d2da50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ should change the heading of the (upcoming) version to include a major version b ## @rjsf/core - BREAKING CHANGE: ShowErrorList prop changed to support `false`, `top` or `bottom`; `true` is no longer a valid value as the default changed from `true` to `top` [#634](https://github.com/rjsf-team/react-jsonschema-form/issues/634) - Added the new generic, `S extends StrictRJSFSchema = RJSFSchema`, for `schema`/`rootSchema` to every component that needed it. +- Fix omitExtraData with field names with dots #2643 ## @rjsf/utils - Beta-only potentially BREAKING CHANGE: Changed all types that directly or indirectly defined `schema`/`rootSchema` to add the generic `S extends StrictRJSFSchema = RJSFSchema` and use `S` as the type for them. diff --git a/packages/core/src/components/Form.tsx b/packages/core/src/components/Form.tsx index dfe0672046..3627764515 100644 --- a/packages/core/src/components/Form.tsx +++ b/packages/core/src/components/Form.tsx @@ -453,13 +453,17 @@ export default class Form< * @param formData - The data for the `Form` * @param fields - The fields to keep while filtering */ - getUsedFormData = (formData: T, fields: string[]): T => { + getUsedFormData = (formData: T, fields: string[][]): T => { // For the case of a single input form if (fields.length === 0 && typeof formData !== "object") { return formData; } - const data: GenericObjectType = _pick(formData, fields); + // _pick has incorrect type definition, it works with string[][], because lodash/hasIn supports it + const data: GenericObjectType = _pick( + formData, + fields as unknown as string[] + ); if (Array.isArray(formData)) { return Object.keys(data).map((key: string) => data[key]) as unknown as T; } @@ -472,15 +476,15 @@ export default class Form< * @param pathSchema - The `PathSchema` object for the form * @param formData - The form data to use while checking for empty objects/arrays */ - getFieldNames = (pathSchema: PathSchema, formData: T) => { + getFieldNames = (pathSchema: PathSchema, formData: T): string[][] => { const getAllPaths = ( _obj: GenericObjectType, - acc: string[] = [], - paths = [""] + acc: string[][] = [], + paths: string[][] = [[]] ) => { Object.keys(_obj).forEach((key: string) => { if (typeof _obj[key] === "object") { - const newPaths = paths.map((path) => `${path}.${key}`); + const newPaths = paths.map((path) => [...path, key]); // If an object is marked with additionalProperties, all its keys are valid if ( _obj[key][RJSF_ADDITONAL_PROPERTIES_FLAG] && @@ -492,7 +496,6 @@ export default class Form< } } else if (key === NAME_KEY && _obj[key] !== "") { paths.forEach((path) => { - path = path.replace(/^\./, ""); const formValue = _get(formData, path); // adds path to fieldNames if it points to a value // or an empty object/array diff --git a/packages/core/test/Form_test.js b/packages/core/test/Form_test.js index 26dd4e6c47..9454aaf611 100644 --- a/packages/core/test/Form_test.js +++ b/packages/core/test/Form_test.js @@ -3073,10 +3073,10 @@ describe("Form omitExtraData and liveOmit", () => { const fieldNames = comp.getFieldNames(pathSchema, formData); expect(fieldNames.sort()).eql( [ - "level1a", - "level1.level2", - "level1.anotherThing.anotherThingNested", - "level1.anotherThing.anotherThingNested2", + ["level1", "anotherThing", "anotherThingNested"], + ["level1", "anotherThing", "anotherThingNested2"], + ["level1", "level2"], + ["level1a"], ].sort() ); }); @@ -3124,7 +3124,7 @@ describe("Form omitExtraData and liveOmit", () => { const fieldNames = comp.getFieldNames(pathSchema, formData); expect(fieldNames.sort()).eql( - ["level1a", "level1.level2", "level1.mixedMap"].sort() + [["level1", "level2"], "level1.mixedMap", ["level1a"]].sort() ); }); @@ -3186,12 +3186,12 @@ describe("Form omitExtraData and liveOmit", () => { const fieldNames = comp.getFieldNames(pathSchema, formData); expect(fieldNames.sort()).eql( [ - "address_list.0.city", - "address_list.0.state", - "address_list.0.street_address", - "address_list.1.city", - "address_list.1.state", - "address_list.1.street_address", + ["address_list", "0", "city"], + ["address_list", "0", "state"], + ["address_list", "0", "street_address"], + ["address_list", "1", "city"], + ["address_list", "1", "state"], + ["address_list", "1", "street_address"], ].sort() ); });