From ff30a2fcda4fe78eb17fbff2a144f87acafa0417 Mon Sep 17 00:00:00 2001 From: Haroen Viaene Date: Thu, 16 May 2019 14:51:01 +0200 Subject: [PATCH] refactor(lodash): isPlainObject The values this function was used for seemed like they can only be arrays or objects to me. We will only want to empty out "breadth-first", so empty objects will stay in the output if they became empty because of the function itself. isEmpty here is removed in #2442, and still works the same (but will need a rebase) The newly added tests also pass with the previous implementation The function is only used in `onSearchStateChange` as a response to a `cleanUp` (caused by unmount) on a widget IFW-743 --- .../src/core/__tests__/utils.js | 21 ++++++++++++++++++- .../src/core/utils.ts | 18 ++++++++++------ 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/packages/react-instantsearch-core/src/core/__tests__/utils.js b/packages/react-instantsearch-core/src/core/__tests__/utils.js index 59b1e9cce8..585f12127d 100644 --- a/packages/react-instantsearch-core/src/core/__tests__/utils.js +++ b/packages/react-instantsearch-core/src/core/__tests__/utils.js @@ -38,7 +38,7 @@ describe('utils', () => { }); }); - describe('remove empty key', () => { + describe.only('remove empty key', () => { it('empty key should be removed', () => { const state = { query: '', @@ -98,6 +98,25 @@ describe('utils', () => { }, }); }); + + it('does not do anything on empty root', () => { + expect(utils.removeEmptyKey({})).toEqual({}); + }); + + it('does empty out objects', () => { + expect(utils.removeEmptyKey({ test: {} })).toEqual({}); + expect(utils.removeEmptyKey({ test: { dog: {} } })).toEqual({ + // this one stays, because we have no multipass algorithm + test: {}, + }); + }); + + it('does not empty out arrays', () => { + expect(utils.removeEmptyKey({ test: [] })).toEqual({ test: [] }); + expect(utils.removeEmptyKey({ test: { dog: [] } })).toEqual({ + test: { dog: [] }, + }); + }); }); describe('addAbsolutePositions', () => { diff --git a/packages/react-instantsearch-core/src/core/utils.ts b/packages/react-instantsearch-core/src/core/utils.ts index c457db7040..46171494a4 100644 --- a/packages/react-instantsearch-core/src/core/utils.ts +++ b/packages/react-instantsearch-core/src/core/utils.ts @@ -1,4 +1,4 @@ -import { isEmpty, isPlainObject } from 'lodash'; +import { isEmpty } from 'lodash'; // From https://github.com/reactjs/react-redux/blob/master/src/utils/shallowEqual.js export const shallowEqual = (objA, objB) => { @@ -33,13 +33,19 @@ export const defer = f => { resolved.then(f); }; -export const removeEmptyKey = obj => { +const isPlainObject = (value: any): value is object => + typeof value === 'object' && value !== null && !Array.isArray(value); + +export const removeEmptyKey = (obj: object) => { Object.keys(obj).forEach(key => { - const value = obj[key]; - if (isEmpty(value) && isPlainObject(value)) { + if (!isPlainObject(obj[key])) { + return; + } + + if (isEmpty(obj[key])) { delete obj[key]; - } else if (isPlainObject(value)) { - removeEmptyKey(value); + } else { + removeEmptyKey(obj[key]); } });