Skip to content

Commit

Permalink
Merge pull request #4082 from marmelab/Fix-form-breaks-when-setting-c…
Browse files Browse the repository at this point in the history
…omplex-value

Fix Form breaks when setting undefined value to object
  • Loading branch information
djhi authored Nov 29, 2019
2 parents e29b1e7 + e1a2f9e commit 9118a70
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 6 deletions.
48 changes: 48 additions & 0 deletions packages/ra-core/src/form/sanitizeEmptyValues.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import expect from 'expect';
import sanitizeEmptyValues from './sanitizeEmptyValues';

describe('sanitizeEmptyValues', () => {
it('should set null or undefined values to null', () => {
expect(sanitizeEmptyValues({ foo: 23 }, {})).toEqual({ foo: null });
expect(sanitizeEmptyValues({ foo: 'hello' }, {})).toEqual({
foo: null,
});
expect(sanitizeEmptyValues({ foo: new Date() }, {})).toEqual({
foo: null,
});
expect(sanitizeEmptyValues({ foo: { bar: 2 } }, {})).toEqual({
foo: null,
});
});
it('should set null or undefined deep values to null', () => {
expect(sanitizeEmptyValues({ foo: { bar: 1 } }, { foo: {} })).toEqual({
foo: { bar: null },
});
});
it('should accept string values', () => {
const str = 'hello';
expect(sanitizeEmptyValues({ str: null }, { str })).toEqual({ str });
expect(sanitizeEmptyValues({}, { str })).toEqual({ str });
});
it('should accept date values', () => {
const date = new Date();
expect(sanitizeEmptyValues({ date: null }, { date })).toEqual({ date });
expect(sanitizeEmptyValues({}, { date })).toEqual({ date });
});
it('should accept array values', () => {
const arr = [1, 2, 3];
expect(sanitizeEmptyValues({ arr: null }, { arr })).toEqual({ arr });
expect(sanitizeEmptyValues({}, { arr })).toEqual({ arr });
});
it('should accept object values', () => {
const obj = { foo: 1 };
expect(sanitizeEmptyValues({ obj: null }, { obj })).toEqual({ obj });
expect(sanitizeEmptyValues({}, { obj })).toEqual({ obj });
});
it('should accept deep object values', () => {
const obj = { foo: { bar: 1 } };
expect(
sanitizeEmptyValues({ obj: { foo: null, foo2: 2 } }, { obj })
).toEqual({ obj: { foo: { bar: 1 }, foo2: null } });
});
});
18 changes: 12 additions & 6 deletions packages/ra-core/src/form/sanitizeEmptyValues.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,36 @@ import merge from 'lodash/merge';
/**
* Because final-form removes undefined and empty string values completely
* (the key for the empty field is removed from the values), we have to check
* wether this value was initially provided so that it is correctly sent to
* whether this value was initially provided so that it is correctly sent to
* the backend.
* See https://github.com/final-form/react-final-form/issues/130#issuecomment-493447888
* @see https://github.com/final-form/react-final-form/issues/130#issuecomment-493447888
*
* @param initialValues The initial values provided to the form
* @param values The current form values
*/
const sanitizeEmptyValues = (initialValues: object, values: object) => {
// For every field initialy provided, we check wether it value has been removed
// For every field initially provided, we check whether it value has been removed
// and set it explicitly to an empty string
if (!initialValues) return values;
const initialValuesWithEmptyFields = Object.keys(initialValues).reduce(
(acc, key) => {
if (typeof values[key] === 'object' && values[key] !== null) {
if (values[key] instanceof Date || Array.isArray(values[key])) {
acc[key] = values[key];
} else if (
typeof values[key] === 'object' &&
values[key] !== null
) {
acc[key] = sanitizeEmptyValues(initialValues[key], values[key]);
} else {
acc[key] =
typeof values[key] === 'undefined' ? '' : values[key];
typeof values[key] === 'undefined' ? null : values[key];
}
return acc;
},
{}
);

// Finaly, we merge back the values to not miss any which wasn't initialy provided
// Finally, we merge back the values to not miss any which wasn't initially provided
return merge(initialValuesWithEmptyFields, values);
};

Expand Down

0 comments on commit 9118a70

Please sign in to comment.