Skip to content

Commit

Permalink
fix(numericSelector): do not change state on init (#1280)
Browse files Browse the repository at this point in the history
We were calling a helper method that was resetting the page to 0.

fixes #1253
  • Loading branch information
vvo authored Sep 14, 2016
1 parent 90c9b70 commit cf27db3
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 21 deletions.
3 changes: 2 additions & 1 deletion docs/examples/tourism/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
var search = instantsearch({
appId: 'latency',
apiKey: '6be0576ff61c053d5f9a3225e2a90f76',
indexName: 'airbnb'
indexName: 'airbnb',
urlSync: true
});

search.addWidget(
Expand Down
39 changes: 32 additions & 7 deletions src/widgets/numeric-selector/__tests__/numeric-selector-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ describe('numericSelector()', () => {
helper = {
addNumericRefinement: sinon.spy(),
clearRefinements: sinon.spy(),
getRefinements: sinon.stub().returns([]),
search: sinon.spy()
};
results = {
Expand All @@ -66,8 +65,31 @@ describe('numericSelector()', () => {
helper.addNumericRefinement.reset();
});

it('doesn\'t configure anything', () => {
expect(widget.getConfiguration).toEqual(undefined);
it('configures the right numericRefinement', () => {
expect(widget.getConfiguration({}, {})).toEqual({
numericRefinements: {
aNumAttr: {
'=': [1]
}
}
});
});

it('configures the right numericRefinement when present in the url', () => {
const urlState = {
numericRefinements: {
aNumAttr: {
'=': [2]
}
}
};
expect(widget.getConfiguration({}, urlState)).toEqual({
numericRefinements: {
aNumAttr: {
'=': [2]
}
}
});
});

it('calls twice ReactDOM.render(<Selector props />, container)', () => {
Expand All @@ -82,10 +104,13 @@ describe('numericSelector()', () => {
});

it('computes refined values and pass them to <Selector props />', () => {
helper.getRefinements = sinon.stub().returns([{
operator: '=',
value: [20]
}]);
helper.state = {
numericRefinements: {
aNumAttr: {
'=': [20]
}
}
};
expectedProps.currentValue = 20;
widget.render({helper, results, state: helper.state});
expect(ReactDOM.render.firstCall.args[0]).toEqualJSX(<Selector {...expectedProps} />);
Expand Down
36 changes: 23 additions & 13 deletions src/widgets/numeric-selector/numeric-selector.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {
getContainerNode
} from '../../lib/utils.js';
import cx from 'classnames';
import find from 'lodash/find';
import autoHideContainerHOC from '../../decorators/autoHideContainer.js';
import SelectorComponent from '../../components/Selector.js';

Expand Down Expand Up @@ -59,12 +58,16 @@ function numericSelector({
};

return {
getConfiguration(currentSearchParameters, searchParametersFromUrl) {
return {
numericRefinements: {
[attributeName]: {
[operator]: [this._getRefinedValue(searchParametersFromUrl)]
}
}
};
},
init({helper}) {
const currentValue = this._getRefinedValue(helper);
if (currentValue !== undefined) {
helper.addNumericRefinement(attributeName, operator, currentValue);
}

this._refine = value => {
helper.clearRefinements(attributeName);
if (value !== undefined) {
Expand All @@ -78,7 +81,7 @@ function numericSelector({
ReactDOM.render(
<Selector
cssClasses={cssClasses}
currentValue={this._getRefinedValue(helper)}
currentValue={this._getRefinedValue(helper.state)}
options={options}
setValue={this._refine}
shouldAutoHideContainer={results.nbHits === 0}
Expand All @@ -87,12 +90,19 @@ function numericSelector({
);
},

_getRefinedValue(helper) {
const refinements = helper.getRefinements(attributeName);
const refinedValue = find(refinements, {operator});
return refinedValue &&
refinedValue.value !== undefined &&
refinedValue.value[0] !== undefined ? refinedValue.value[0] : options[0].value;
_getRefinedValue(state) {
// This is reimplementing state.getNumericRefinement
// But searchParametersFromUrl is not an actual SearchParameters object
// It's only the object structure without the methods, because getStateFromQueryString
// is not sending a SearchParameters. There's no way given how web built the helper
// to initialize a true partial state where only the refinements are present
return state &&
state.numericRefinements &&
state.numericRefinements[attributeName] !== undefined &&
state.numericRefinements[attributeName][operator] !== undefined &&
state.numericRefinements[attributeName][operator][0] !== undefined ? // could be 0
state.numericRefinements[attributeName][operator][0] :
options[0].value;
}
};
}
Expand Down

0 comments on commit cf27db3

Please sign in to comment.