Skip to content

Commit

Permalink
Fix omitExtraData bugs for nested empties and nonspecified objects (#…
Browse files Browse the repository at this point in the history
…1419)

* Fixed disappearing empty objects and arrays

* Fixed some tests

* Fixed bugs

* Updated toPathSchema tests

* Added tests from #1418

* Uncommented test cases

* Remove unecessary or

* Update usage of toPathSchema

* Revert back to old period separation style in toPathSchema

* Converted change props with liveOmit test to only test for liveOmit

* Revert one other case of period positioning

* Changed according to review suggestions
  • Loading branch information
Tonexus authored and epicfaace committed Aug 22, 2019
1 parent d2112d3 commit 4251a2c
Show file tree
Hide file tree
Showing 5 changed files with 910 additions and 649 deletions.
60 changes: 36 additions & 24 deletions src/components/Form.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { Component } from "react";
import PropTypes from "prop-types";
import _pick from "lodash/pick";
import _get from "lodash/get";
import _isEmpty from "lodash/isEmpty";

import { default as DefaultErrorList } from "./ErrorList";
import {
Expand Down Expand Up @@ -78,7 +79,6 @@ export default class Form extends Component {
formData,
props.idPrefix
);
const pathSchema = toPathSchema(retrievedSchema, "", definitions, formData);
return {
schema,
uiSchema,
Expand All @@ -88,7 +88,6 @@ export default class Form extends Component {
errors,
errorSchema,
additionalMetaSchemas,
pathSchema,
};
}

Expand Down Expand Up @@ -148,23 +147,18 @@ export default class Form extends Component {
};

getFieldNames = (pathSchema, formData) => {
const getAllPaths = (_obj, acc = [], paths = []) => {
const getAllPaths = (_obj, acc = [], paths = [""]) => {
Object.keys(_obj).forEach(key => {
if (typeof _obj[key] === "object") {
if (!paths.length) {
getAllPaths(_obj[key], acc, [key]);
} else {
let newPaths = [];
paths.forEach(path => {
newPaths.push(path);
});
newPaths = newPaths.map(path => `${path}.${key}`);
getAllPaths(_obj[key], acc, newPaths);
}
} else if (key === "$name") {
let newPaths = paths.map(path => `${path}.${key}`);
getAllPaths(_obj[key], acc, newPaths);
} else if (key === "$name" && _obj[key] !== "") {
paths.forEach(path => {
path = path.replace(/^\./, "");
const formValue = _get(formData, path);
if (typeof formValue !== "object") {
// adds path to fieldNames if it points to a value
// or an empty object/array
if (typeof formValue !== "object" || _isEmpty(formValue)) {
acc.push(path);
}
});
Expand All @@ -186,13 +180,20 @@ export default class Form extends Component {
let newFormData = formData;

if (this.props.omitExtraData === true && this.props.liveOmit === true) {
const newState = this.getStateFromProps(this.props, formData);

const fieldNames = this.getFieldNames(
newState.pathSchema,
newState.formData
const retrievedSchema = retrieveSchema(
this.state.schema,
this.state.schema.definitions,
formData
);
const pathSchema = toPathSchema(
retrievedSchema,
"",
this.state.schema.definitions,
formData
);

const fieldNames = this.getFieldNames(pathSchema, formData);

newFormData = this.getUsedFormData(formData, fieldNames);
state = {
formData: newFormData,
Expand Down Expand Up @@ -237,11 +238,22 @@ export default class Form extends Component {
event.persist();
let newFormData = this.state.formData;

const { pathSchema } = this.state;

if (this.props.omitExtraData === true) {
const fieldNames = this.getFieldNames(pathSchema, this.state.formData);
newFormData = this.getUsedFormData(this.state.formData, fieldNames);
const retrievedSchema = retrieveSchema(
this.state.schema,
this.state.schema.definitions,
newFormData
);
const pathSchema = toPathSchema(
retrievedSchema,
"",
this.state.schema.definitions,
newFormData
);

const fieldNames = this.getFieldNames(pathSchema, newFormData);

newFormData = this.getUsedFormData(newFormData, fieldNames);
}

if (!this.props.noValidate) {
Expand Down
51 changes: 20 additions & 31 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -884,43 +884,32 @@ export function toIdSchema(

export function toPathSchema(schema, name = "", definitions, formData = {}) {
const pathSchema = {
$name: name,
$name: name.replace(/^\./, ""),
};
if ("$ref" in schema || "dependencies" in schema) {
const _schema = retrieveSchema(schema, definitions, formData);
return toPathSchema(_schema, name, definitions, formData);
}
if ("items" in schema) {
const retVal = {};
if (Array.isArray(formData) && formData.length > 0) {
formData.forEach((element, index) => {
retVal[`${index}`] = toPathSchema(
schema.items,
`${name}.${index}`,
definitions,
element
);
});
if (schema.hasOwnProperty("items") && Array.isArray(formData)) {
formData.forEach((element, i) => {
pathSchema[i] = toPathSchema(
schema.items,
`${name}.${i}`,
definitions,
element
);
});
} else if (schema.hasOwnProperty("properties")) {
for (const property in schema.properties) {
pathSchema[property] = toPathSchema(
schema.properties[property],
`${name}.${property}`,
definitions,
// It's possible that formData is not an object -- this can happen if an
// array item has just been added, but not populated with data yet
(formData || {})[property]
);
}
return retVal;
}
if (schema.type !== "object") {
return pathSchema;
}
for (const property in schema.properties || {}) {
const field = schema.properties[property];
const fieldId = pathSchema.$name
? pathSchema.$name + "." + property
: property;

pathSchema[property] = toPathSchema(
field,
fieldId,
definitions,
// It's possible that formData is not an object -- this can happen if an
// array item has just been added, but not populated with data yet
(formData || {})[property]
);
}
return pathSchema;
}
Expand Down
Loading

0 comments on commit 4251a2c

Please sign in to comment.