From 0628776eb5e1d99aea5db57bc66676789219818a Mon Sep 17 00:00:00 2001 From: Samuel Vaillant Date: Tue, 9 Jul 2019 17:12:18 +0200 Subject: [PATCH] fix(index): prevent render without results (#3932) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(index): prevent render without results * refactor(InstantSearch): search stalled false by default * docs: comments wording Co-Authored-By: François Chalifour --- src/lib/InstantSearch.js | 4 +-- src/lib/__tests__/InstantSearch-test.js | 19 ------------- src/widgets/index/__tests__/index-test.ts | 34 +++++++++++++++++++++++ src/widgets/index/index.ts | 14 ++++++---- 4 files changed, 44 insertions(+), 27 deletions(-) diff --git a/src/lib/InstantSearch.js b/src/lib/InstantSearch.js index 1cb0eff0e8..b581aded42 100644 --- a/src/lib/InstantSearch.js +++ b/src/lib/InstantSearch.js @@ -108,7 +108,7 @@ See: https://www.algolia.com/doc/guides/building-search-ui/going-further/backend this._stalledSearchDelay = stalledSearchDelay; this._searchStalledTimer = null; - this._isSearchStalled = true; + this._isSearchStalled = false; this._searchParameters = { ...searchParameters, index: indexName, @@ -351,7 +351,7 @@ See: https://www.algolia.com/doc/guides/building-search-ui/going-further/backend }); scheduleStalledRender() { - if (!this._isSearchStalled && !this._searchStalledTimer) { + if (!this._searchStalledTimer) { this._searchStalledTimer = setTimeout(() => { this._isSearchStalled = true; this.scheduleRender(); diff --git a/src/lib/__tests__/InstantSearch-test.js b/src/lib/__tests__/InstantSearch-test.js index bf2b99f5d0..fd3bb79de4 100644 --- a/src/lib/__tests__/InstantSearch-test.js +++ b/src/lib/__tests__/InstantSearch-test.js @@ -961,25 +961,6 @@ describe('scheduleStalledRender', () => { }) ); }); - - // https://github.com/algolia/instantsearch.js/pull/2623 - it('does not trigger a re-`render` without results', () => { - const { searchClient } = createControlledSearchClient(); - const search = new InstantSearch({ - indexName: 'index_name', - searchClient, - }); - - search.start(); - - search.addWidget({ - render: () => {}, - }); - - jest.runOnlyPendingTimers(); - - return runAllMicroTasks(); - }); }); describe('createURL', () => { diff --git a/src/widgets/index/__tests__/index-test.ts b/src/widgets/index/__tests__/index-test.ts index 80030da75e..e93ba2e9aa 100644 --- a/src/widgets/index/__tests__/index-test.ts +++ b/src/widgets/index/__tests__/index-test.ts @@ -745,6 +745,40 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/index/js/" }); }); }); + + // https://github.com/algolia/instantsearch.js/pull/2623 + it('does not call `render` without `lastResults`', () => { + const instance = index({ indexName: 'index_name' }); + const instantSearchInstance = createInstantSearch(); + + const widgets = [createSearchBox(), createPagination()]; + + instance.addWidgets(widgets); + + widgets.forEach(widget => { + expect(widget.render).toHaveBeenCalledTimes(0); + }); + + instance.init( + createInitOptions({ + instantSearchInstance, + }) + ); + + widgets.forEach(widget => { + expect(widget.render).toHaveBeenCalledTimes(0); + }); + + instance.render( + createRenderOptions({ + instantSearchInstance, + }) + ); + + widgets.forEach(widget => { + expect(widget.render).toHaveBeenCalledTimes(0); + }); + }); }); describe('dispose', () => { diff --git a/src/widgets/index/index.ts b/src/widgets/index/index.ts index 61d0126e09..fed9b47492 100644 --- a/src/widgets/index/index.ts +++ b/src/widgets/index/index.ts @@ -238,16 +238,18 @@ const index = (props: IndexProps): Index => { render({ instantSearchInstance }) { localWidgets.forEach(widget => { // At this point, all the variables used below are set. Both `helper` - // and `derivedHelper` has been created at the `init` step. The attribute - // `lastResults` is set before the event `result` is emitted. At this stage, - // the event has emitted hence the value is already set. + // and `derivedHelper` have been created at the `init` step. The attribute + // `lastResults` might be `null` though. It's possible that a stalled render + // happens before the result e.g with a dynamically added index the request might + // be delayed. The render is triggered for the complete tree but some parts do + // not have results yet. - if (widget.render) { + if (widget.render && derivedHelper!.lastResults) { widget.render({ helper: helper!, instantSearchInstance, - results: derivedHelper!.lastResults!, - state: derivedHelper!.lastResults!._state, + results: derivedHelper!.lastResults, + state: derivedHelper!.lastResults._state, templatesConfig: instantSearchInstance.templatesConfig, createURL: instantSearchInstance._createAbsoluteURL, searchMetadata: {