Skip to content

Commit 9490ca9

Browse files
samoussHaroenv
authored andcommitted
fix(index): subscribe to state change only after init for uiState (#4003)
1 parent fe11774 commit 9490ca9

File tree

2 files changed

+55
-6
lines changed

2 files changed

+55
-6
lines changed

src/widgets/index/__tests__/index-test.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -862,6 +862,43 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/index/js/"
862862
});
863863
});
864864

865+
it('does not update the local `uiState` on state changes in `init`', () => {
866+
const instance = index({ indexName: 'index_name' });
867+
const instantSearchInstance = createInstantSearch();
868+
const widgets = [
869+
createSearchBox(),
870+
createPagination(),
871+
createWidget({
872+
init({ helper }) {
873+
helper
874+
.setQueryParameter('query', 'Apple iPhone')
875+
.setQueryParameter('page', 5);
876+
},
877+
}),
878+
];
879+
880+
instance.addWidgets(widgets);
881+
882+
instance.init(
883+
createInitOptions({
884+
instantSearchInstance,
885+
})
886+
);
887+
888+
expect(instance.getHelper()!.state).toEqual(
889+
new SearchParameters({
890+
index: 'index_name',
891+
query: 'Apple iPhone',
892+
page: 5,
893+
})
894+
);
895+
896+
expect(instance.getWidgetState({})).toEqual({
897+
// eslint-disable-next-line @typescript-eslint/camelcase
898+
index_name: {},
899+
});
900+
});
901+
865902
it('updates the local `uiState` only with widgets not indices', () => {
866903
const level0 = index({ indexName: 'level_0_index_name' });
867904
const level1 = index({ indexName: 'level_1_index_name' });

src/widgets/index/index.ts

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -286,12 +286,11 @@ const index = (props: IndexProps): Index => {
286286
mergeSearchParameters(...resolveSearchParameters(this))
287287
);
288288

289-
helper.on('change', ({ state, isPageReset }) => {
290-
localUiState = getLocalWidgetsState(localWidgets, {
291-
searchParameters: state,
292-
helper: helper!,
293-
});
294-
289+
// Subscribe to the Helper state changes for the page before widgets
290+
// are initialized. This behavior mimics the original one of the Helper.
291+
// It makes sense to replicate it at the `init` step. We have another
292+
// listener on `change` below, once `init` is done.
293+
helper.on('change', ({ isPageReset }) => {
295294
if (isPageReset) {
296295
resetPageFromWidgets(localWidgets);
297296
}
@@ -324,6 +323,19 @@ const index = (props: IndexProps): Index => {
324323
});
325324
}
326325
});
326+
327+
// Subscribe to the Helper state changes for the `uiState` once widgets
328+
// are initialized. Until the first render, state changes are part of the
329+
// configuration step. This is mainly for backward compatibility with custom
330+
// widgets. When the subscription happens before the `init` step, the (static)
331+
// configuration of the widget is pushed in the URL. That's what we want to avoid.
332+
// https://github.com/algolia/instantsearch.js/pull/994/commits/4a672ae3fd78809e213de0368549ef12e9dc9454
333+
helper.on('change', ({ state }) => {
334+
localUiState = getLocalWidgetsState(localWidgets, {
335+
searchParameters: state,
336+
helper: helper!,
337+
});
338+
});
327339
},
328340

329341
render({ instantSearchInstance }: IndexRenderOptions) {

0 commit comments

Comments
 (0)