From bc0f9e245f28fe7ee6f9578c86ae833607d36145 Mon Sep 17 00:00:00 2001 From: Samuel Vaillant Date: Mon, 12 Aug 2019 13:31:40 +0200 Subject: [PATCH] fix(connectSortBy): never update the initial index (#4015) * fix(connectSortBy): never update the initial index * chore: review comment wording --- .../sort-by/__tests__/connectSortBy-test.js | 43 +++++++++++++++++++ src/connectors/sort-by/connectSortBy.js | 24 ++++++++--- 2 files changed, 60 insertions(+), 7 deletions(-) diff --git a/src/connectors/sort-by/__tests__/connectSortBy-test.js b/src/connectors/sort-by/__tests__/connectSortBy-test.js index 5c18f29d70..e2295627bf 100644 --- a/src/connectors/sort-by/__tests__/connectSortBy-test.js +++ b/src/connectors/sort-by/__tests__/connectSortBy-test.js @@ -373,6 +373,49 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/sort-by/js/ }); expect(uiStateAfter).toBe(uiStateBefore); }); + + test('should use the top-level `indexName` for the initial index', () => { + const render = () => {}; + const makeWidget = connectSortBy(render); + const instantSearchInstance = instantSearch({ + indexName: 'initial_index_name', + searchClient: { search() {} }, + }); + + const widget = makeWidget({ + items: [ + { label: 'Sort products', value: 'initial_index_name' }, + { label: 'Sort products by price', value: 'index_name_price' }, + { label: 'Sort products by magic', value: 'index_name_magic' }, + ], + }); + + const helper = jsHelper({}, 'initial_index_name'); + helper.search = jest.fn(); + + // Simulate an URLSync + helper.setQueryParameter('index', 'index_name_price'); + + widget.init({ + helper, + state: helper.state, + createURL: () => '#', + onHistoryChange: () => {}, + instantSearchInstance, + }); + + const actual = widget.getWidgetState( + {}, + { + searchParameters: helper.state, + helper, + } + ); + + expect(actual).toEqual({ + sortBy: 'index_name_price', + }); + }); }); describe('getWidgetSearchParameters', () => { diff --git a/src/connectors/sort-by/connectSortBy.js b/src/connectors/sort-by/connectSortBy.js index 10f809e41a..fc2b9a6123 100644 --- a/src/connectors/sort-by/connectSortBy.js +++ b/src/connectors/sort-by/connectSortBy.js @@ -102,25 +102,35 @@ export default function connectSortBy(renderFn, unmountFn = noop) { return { init({ helper, instantSearchInstance }) { - const initialIndex = helper.state.index; - const isInitialIndexInItems = find( + const currentIndex = helper.state.index; + const isCurrentIndexInItems = find( items, - item => item.value === initialIndex + item => item.value === currentIndex ); - this.initialIndex = initialIndex; + // The `initialIndex` is the one set at the top level not the one used + // at `init`. The value of `index` at `init` could come from the URL. We + // want the "real" initial value, this one should never change. If it changes + // between the lifecycles of the widget the current refinement won't be + // pushed into the `uiState`. Because we never push the "initial" value to + // avoid to pollute the URL. + // Note that it might be interesting to manage this at the state mapping + // level and always push the index value into the `uiState`. It is a + // breaking change. + // @MAJOR + this.initialIndex = instantSearchInstance.indexName; this.setIndex = indexName => { helper.setIndex(indexName).search(); }; warning( - isInitialIndexInItems, - `The index named "${initialIndex}" is not listed in the \`items\` of \`sortBy\`.` + isCurrentIndexInItems, + `The index named "${currentIndex}" is not listed in the \`items\` of \`sortBy\`.` ); renderFn( { - currentRefinement: initialIndex, + currentRefinement: currentIndex, options: transformItems(items), refine: this.setIndex, hasNoResults: true,