Skip to content

Commit 07d1fea

Browse files
author
vvo
committed
fix(lifecycle): save configuration done in widget.init
Before this commit, every configuration done in widget.init would not be remembered when going back in the browser history. Scenario: You built a custom widget using helper.setQueryParameter in widget.init. Then you load "/", widget.init() sets some helper params, you go to page 2, you click on <= back. Before this commit we would forget what was done in widget.init(). Now it works. This was needed to fix the "rootPath" option of the hierarchicalMenu. The rootPath option triggers a state change from inside the helper (which may have been a bad idea after all) => it was not remembered when going back to empty url. Thanks to @maxiloc for the bug report and big help solving this!
1 parent 624da3f commit 07d1fea

File tree

4 files changed

+38
-7
lines changed

4 files changed

+38
-7
lines changed

dev/app.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ search.addWidget(
305305
link: 'facet-value',
306306
count: 'facet-count pull-right'
307307
},
308+
rootPath: 'Cameras & Camcorders > Digital Camera Accessories',
308309
templates: {
309310
header: 'Hierarchical categories'
310311
}

dev/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,11 @@ <h1><a href="./">Instant search demo</a> <small>using instantsearch.js</small></
6767
</div>
6868
</div>
6969
</div>
70+
<div id="pagination" class="text-center"></div>
7071
<h3>Results overview</h3>
7172
<div id="hits-table"></div>
7273
<h3>Results</h3>
7374
<div id="hits"></div>
74-
<div id="pagination" class="text-center"></div>
7575
</div>
7676
</div>
7777
</div>

src/lib/InstantSearch.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,14 +102,15 @@ Usage: instantsearch({
102102
start() {
103103
if (!this.widgets) throw new Error('No widgets were added to instantsearch.js');
104104

105+
let syncWidget;
106+
105107
if (this.urlSync) {
106-
let syncWidget = urlSyncWidget(this.urlSync);
108+
syncWidget = urlSyncWidget(this.urlSync);
107109
this._createURL = syncWidget.createURL.bind(syncWidget);
108110
this._onHistoryChange = syncWidget.onHistoryChange.bind(syncWidget);
109-
this.widgets.push(syncWidget);
110111
} else {
111112
this._createURL = defaultCreateURL;
112-
this._onHistoryChange = function() {};
113+
this._onHistoryChange = () => {};
113114
}
114115

115116
this.searchParameters = this.widgets.reduce(enhanceConfiguration, this.searchParameters);
@@ -128,6 +129,12 @@ Usage: instantsearch({
128129
this.helper = helper;
129130

130131
this._init(helper.state, helper);
132+
133+
if (this.urlSync) {
134+
helper.setState(enhanceConfiguration(helper.state, syncWidget));
135+
syncWidget.init({helper});
136+
}
137+
131138
helper.on('result', this._render.bind(this, helper));
132139
helper.search();
133140
}

src/lib/__tests__/InstantSearch-test.js

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ describe('InstantSearch lifecycle', () => {
2323
let searchParameters;
2424
let search;
2525
let helperSearchSpy;
26+
let urlSync;
2627

2728
beforeEach(() => {
2829
client = {algolia: 'client', addAlgoliaAgent: () => {}};
@@ -33,10 +34,18 @@ describe('InstantSearch lifecycle', () => {
3334
helperSearchSpy = sinon.spy();
3435
helper.search = helperSearchSpy;
3536
helper.getState = sinon.stub().returns({});
37+
helper.setState = sinon.spy();
3638
helper.state = {
3739
setQueryParameters: function(params) { return new SearchParameters(params); }
3840
};
3941

42+
urlSync = {
43+
createURL: sinon.spy(),
44+
onHistoryChange: () => {},
45+
getConfiguration: sinon.spy(),
46+
init: () => {}
47+
};
48+
4049
algoliasearch = sinon.stub().returns(client);
4150
algoliasearchHelper = sinon.stub().returns(helper);
4251

@@ -51,6 +60,7 @@ describe('InstantSearch lifecycle', () => {
5160
another: {config: 'parameter'}
5261
};
5362

63+
InstantSearch.__Rewire__('urlSyncWidget', () => urlSync);
5464
InstantSearch.__Rewire__('algoliasearch', algoliasearch);
5565
InstantSearch.__Rewire__('algoliasearchHelper', algoliasearchHelper);
5666

@@ -64,6 +74,7 @@ describe('InstantSearch lifecycle', () => {
6474
});
6575

6676
afterEach(() => {
77+
InstantSearch.__ResetDependency__('urlSyncWidget');
6778
InstantSearch.__ResetDependency__('algoliasearch');
6879
InstantSearch.__ResetDependency__('algoliasearchHelper');
6980
});
@@ -111,7 +122,9 @@ describe('InstantSearch lifecycle', () => {
111122
beforeEach(() => {
112123
widget = {
113124
getConfiguration: sinon.stub().returns({some: 'modified', another: {different: 'parameter'}}),
114-
init: sinon.spy(),
125+
init: sinon.spy(() => {
126+
helper.state.sendMeToUrlSync = true;
127+
}),
115128
render: sinon.spy()
116129
};
117130
search.addWidget(widget);
@@ -160,6 +173,14 @@ describe('InstantSearch lifecycle', () => {
160173
expect(args.onHistoryChange).toBe(search._onHistoryChange);
161174
});
162175

176+
it('calls urlSync.getConfiguration after every widget', () => {
177+
expect(urlSync.getConfiguration.calledOnce).toBe(true, 'urlSync.getConfiguration called once');
178+
expect(widget.init.calledAfter(widget.getConfiguration))
179+
.toBe(true, 'urlSync.getConfiguration was called after widget.init');
180+
expect(urlSync.getConfiguration.getCall(0).args[0].sendMeToUrlSync)
181+
.toBe(true, 'state modifications done in widget.init should be sent to urlSync.getConfiguration');
182+
});
183+
163184
it('does not call widget.render', () => {
164185
expect(widget.render.notCalled).toBe(true);
165186
});
@@ -235,8 +256,10 @@ describe('InstantSearch lifecycle', () => {
235256
search.start();
236257
});
237258

238-
it('creates a URL', () => {
239-
expect(search.createURL({hitsPerPage: 42})).toEqual('?q=&hPP=42&idx=&p=0');
259+
it('has a createURL method', () => {
260+
search.createURL({hitsPerPage: 542});
261+
expect(urlSync.createURL.calledOnce).toBe(true);
262+
expect(urlSync.createURL.getCall(0).args[0].hitsPerPage).toBe(542);
240263
});
241264

242265
it('emits render when all render are done (using on)', () => {

0 commit comments

Comments
 (0)