Skip to content

Commit

Permalink
feat(searchFunction): make search function provide a better API
Browse files Browse the repository at this point in the history
* feat(searchFunction): Offer full helper support in search function

This implementation offers:
 - a full helper to modify the parameters before sending the request
 - all the other search function (searchOnce, searchForFacetValues)
 - compatibility with async code (no oops effect)

* fix(slider): Make sure the slider doesn't update the state twice

This commit adds constraints to make sure that a refine call doesn't
trigger a new state update and search. It also adds undefined as a
value that can be passed as "no boundary selected" for min and max
in the refine function (slider connector).

* fix(searchFunction): rm unnecessary state update in internals

* chore(naming): change name of search helper function

* chore(test): test searchFunction in a less altered env

The previous setup was not compatible with the kind of manipulation done
for implementing the `searchFunction`.
  • Loading branch information
bobylito authored and iam4x committed Jun 20, 2017
1 parent dc68f46 commit 8fc0831
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 35 deletions.
7 changes: 5 additions & 2 deletions src/components/Slider/Slider.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,17 @@ class Slider extends Component {
return this.props.min === this.props.max;
}

handleChange = ({values}) => {
handleChange = ({min, max, values}) => {
// when Slider is disabled, we alter `min, max` values
// in order to render a "disabled state" Slider. Since we alter
// theses values, Rheostat trigger a "change" event which trigger a new
// search to Algolia with wrong values.
if (!this.isDisabled) {
const {refine} = this.props;
refine(values);
refine([
min === values[0] ? undefined : values[0],
max === values[1] ? undefined : values[1],
]);
}
}

Expand Down
21 changes: 14 additions & 7 deletions src/connectors/range-slider/connectRangeSlider.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,14 +119,21 @@ export default function connectRangeSlider(renderFn) {

init({helper, instantSearchInstance}) {
this._refine = bounds => newValues => {
helper.clearRefinements(attributeName);
if (!bounds.min || newValues[0] > bounds.min) {
helper.addNumericRefinement(attributeName, '>=', formatToNumber(newValues[0]));
const currentValues = [
helper.getNumericRefinement(attributeName, '>='),
helper.getNumericRefinement(attributeName, '<='),
];

if (currentValues[0] !== newValues[0] || currentValues[1] !== newValues[1]) {
helper.clearRefinements(attributeName);
if (!bounds.min || newValues[0] > bounds.min) {
helper.addNumericRefinement(attributeName, '>=', formatToNumber(newValues[0]));
}
if (!bounds.max || newValues[1] < bounds.max) {
helper.addNumericRefinement(attributeName, '<=', formatToNumber(newValues[1]));
}
helper.search();
}
if (!bounds.max || newValues[1] < bounds.max) {
helper.addNumericRefinement(attributeName, '<=', formatToNumber(newValues[1]));
}
helper.search();
};

const stats = {
Expand Down
28 changes: 18 additions & 10 deletions src/lib/InstantSearch.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,19 +121,27 @@ Usage: instantsearch({
);

if (this._searchFunction) {
this.helper = Object.create(helper);
this.helper.search = () => {
helper.setState(this.helper.state);
this._searchFunction(helper);
this._mainHelperSearch = helper.search.bind(helper);
helper.search = () => {
const helperSearchFunction = algoliasearchHelper(
{
addAlgoliaAgent: () => {},
search: () => {},
},
helper.state.index,
helper.state
);
helperSearchFunction.once('search', state => {
helper.overrideStateWithoutTriggeringChangeEvent(state);
this._mainHelperSearch();
});
this._searchFunction(helperSearchFunction);
};
this._init(helper.state, this.helper);
helper.on('result', this._render.bind(this, this.helper));
} else {
this.helper = helper;
this._init(helper.state, this.helper);
this.helper.on('result', this._render.bind(this, this.helper));
}

this.helper = helper;
this._init(helper.state, this.helper);
this.helper.on('result', this._render.bind(this, this.helper));
this.helper.search();
}

Expand Down
38 changes: 38 additions & 0 deletions src/lib/__tests__/InstantSearch-test-2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import sinon from 'sinon';

// import algoliaSearchHelper from 'algoliasearch-helper';
import InstantSearch from '../InstantSearch';

const appId = 'appId';
const apiKey = 'apiKey';
const indexName = 'lifecycle';

describe.only('InstantSearch lifecycle', () => {
it('calls the provided searchFunction when used', () => {
const searchFunctionSpy = sinon.spy(h => {
h.setQuery('test').search();
});

const fakeClient = {
search: sinon.spy(),
addAlgoliaAgent: () => {},
};

const search = new InstantSearch({
appId,
apiKey,
indexName,
searchFunction: searchFunctionSpy,
createAlgoliaClient: () => fakeClient,
});

expect(searchFunctionSpy.callCount).toBe(0);
expect(fakeClient.search.callCount).toBe(0);

search.start();

expect(searchFunctionSpy.callCount).toBe(1);
expect(search.helper.state.query).toBe('test');
expect(fakeClient.search.callCount).toBe(1);
});
});
16 changes: 0 additions & 16 deletions src/lib/__tests__/InstantSearch-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,22 +125,6 @@ describe('InstantSearch lifecycle', () => {
});
});

it('calls the provided searchFunction when used', () => {
const searchSpy = sinon.spy(h => {
h.setQuery('test').search();
});
search = new InstantSearch({
appId,
apiKey,
indexName,
searchFunction: searchSpy,
});
search.start();
expect(searchSpy.calledOnce).toBe(true);
expect(helper.state.query).toBe('test');
expect(helperSearchSpy.calledOnce).toBe(true);
});

it('does not fail when passing same references inside multiple searchParameters props', () => {
const disjunctiveFacetsRefinements = {fruits: ['apple']};
const facetsRefinements = disjunctiveFacetsRefinements;
Expand Down

0 comments on commit 8fc0831

Please sign in to comment.