Skip to content
This repository has been archived by the owner on Feb 2, 2023. It is now read-only.

feat(is-routing): support instantsearch routing #551

Merged
merged 5 commits into from
Aug 8, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
172 changes: 172 additions & 0 deletions src/instantsearch/__snapshots__/widget.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`instantsearch widget routing getWidgetSearchParameters should add the refinements according to the UI state provided 1`] = `
SearchParameters {
"advancedSyntax": undefined,
"allowTyposOnNumericTokens": undefined,
"analytics": undefined,
"analyticsTags": undefined,
"aroundLatLng": "123,123",
"aroundLatLngViaIP": undefined,
"aroundPrecision": undefined,
"aroundRadius": undefined,
"attributesToHighlight": undefined,
"attributesToRetrieve": undefined,
"attributesToSnippet": undefined,
"disableExactOnAttributes": undefined,
"disjunctiveFacets": Array [],
"disjunctiveFacetsRefinements": Object {},
"distinct": undefined,
"enableExactOnSingleWordQuery": undefined,
"facets": Array [],
"facetsExcludes": Object {},
"facetsRefinements": Object {},
"getRankingInfo": undefined,
"hierarchicalFacets": Array [],
"hierarchicalFacetsRefinements": Object {},
"highlightPostTag": undefined,
"highlightPreTag": undefined,
"hitsPerPage": undefined,
"ignorePlurals": undefined,
"index": "",
"insideBoundingBox": undefined,
"insidePolygon": undefined,
"length": undefined,
"maxValuesPerFacet": undefined,
"minProximity": undefined,
"minWordSizefor1Typo": undefined,
"minWordSizefor2Typos": undefined,
"minimumAroundRadius": undefined,
"numericFilters": undefined,
"numericRefinements": Object {},
"offset": undefined,
"optionalFacetFilters": undefined,
"optionalTagFilters": undefined,
"optionalWords": undefined,
"page": 0,
"query": "",
"queryType": undefined,
"removeWordsIfNoResults": undefined,
"replaceSynonymsInHighlight": undefined,
"restrictSearchableAttributes": undefined,
"snippetEllipsisText": undefined,
"synonyms": undefined,
"tagFilters": undefined,
"tagRefinements": Array [],
"typoTolerance": undefined,
}
`;

exports[`instantsearch widget routing getWidgetSearchParameters should enforce the default value if no value is in the UI State 1`] = `
SearchParameters {
"advancedSyntax": undefined,
"allowTyposOnNumericTokens": undefined,
"analytics": undefined,
"analyticsTags": undefined,
"aroundLatLng": "2,2",
"aroundLatLngViaIP": undefined,
"aroundPrecision": undefined,
"aroundRadius": undefined,
"attributesToHighlight": undefined,
"attributesToRetrieve": undefined,
"attributesToSnippet": undefined,
"disableExactOnAttributes": undefined,
"disjunctiveFacets": Array [],
"disjunctiveFacetsRefinements": Object {},
"distinct": undefined,
"enableExactOnSingleWordQuery": undefined,
"facets": Array [],
"facetsExcludes": Object {},
"facetsRefinements": Object {},
"getRankingInfo": undefined,
"hierarchicalFacets": Array [],
"hierarchicalFacetsRefinements": Object {},
"highlightPostTag": undefined,
"highlightPreTag": undefined,
"hitsPerPage": undefined,
"ignorePlurals": undefined,
"index": "",
"insideBoundingBox": undefined,
"insidePolygon": undefined,
"length": undefined,
"maxValuesPerFacet": undefined,
"minProximity": undefined,
"minWordSizefor1Typo": undefined,
"minWordSizefor2Typos": undefined,
"minimumAroundRadius": undefined,
"numericFilters": undefined,
"numericRefinements": Object {},
"offset": undefined,
"optionalFacetFilters": undefined,
"optionalTagFilters": undefined,
"optionalWords": undefined,
"page": 0,
"query": "",
"queryType": undefined,
"removeWordsIfNoResults": undefined,
"replaceSynonymsInHighlight": undefined,
"restrictSearchableAttributes": undefined,
"snippetEllipsisText": undefined,
"synonyms": undefined,
"tagFilters": undefined,
"tagRefinements": Array [],
"typoTolerance": undefined,
}
`;

exports[`instantsearch widget routing getWidgetSearchParameters should reset aroundLatLng if no defaultOptions and no value is in the UI State 1`] = `
SearchParameters {
"advancedSyntax": undefined,
"allowTyposOnNumericTokens": undefined,
"analytics": undefined,
"analyticsTags": undefined,
"aroundLatLng": undefined,
"aroundLatLngViaIP": undefined,
"aroundPrecision": undefined,
"aroundRadius": undefined,
"attributesToHighlight": undefined,
"attributesToRetrieve": undefined,
"attributesToSnippet": undefined,
"disableExactOnAttributes": undefined,
"disjunctiveFacets": Array [],
"disjunctiveFacetsRefinements": Object {},
"distinct": undefined,
"enableExactOnSingleWordQuery": undefined,
"facets": Array [],
"facetsExcludes": Object {},
"facetsRefinements": Object {},
"getRankingInfo": undefined,
"hierarchicalFacets": Array [],
"hierarchicalFacetsRefinements": Object {},
"highlightPostTag": undefined,
"highlightPreTag": undefined,
"hitsPerPage": undefined,
"ignorePlurals": undefined,
"index": "",
"insideBoundingBox": undefined,
"insidePolygon": undefined,
"length": undefined,
"maxValuesPerFacet": undefined,
"minProximity": undefined,
"minWordSizefor1Typo": undefined,
"minWordSizefor2Typos": undefined,
"minimumAroundRadius": undefined,
"numericFilters": undefined,
"numericRefinements": Object {},
"offset": undefined,
"optionalFacetFilters": undefined,
"optionalTagFilters": undefined,
"optionalWords": undefined,
"page": 0,
"query": "",
"queryType": undefined,
"removeWordsIfNoResults": undefined,
"replaceSynonymsInHighlight": undefined,
"restrictSearchableAttributes": undefined,
"snippetEllipsisText": undefined,
"synonyms": undefined,
"tagFilters": undefined,
"tagRefinements": Array [],
"typoTolerance": undefined,
}
`;
67 changes: 61 additions & 6 deletions src/instantsearch/widget.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,34 +10,89 @@ class AlgoliaPlacesWidget {
}

this.placesOptions = placesOptions;
this.placesAutocomplete = places(this.placesOptions);

this.state = {};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not completely sure, but this could be called this.uiState

}
init({ helper }) {
const placesAutocomplete = places(this.placesOptions);

init({ helper }) {
helper
.setQueryParameter('insideBoundingBox')
.setQueryParameter('aroundLatLng', this.defaultPosition);
.setQueryParameter(
'aroundLatLng',
this.state.position || this.defaultPosition
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this.state.position will ever be defined in that case

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can be defined because of the init of the routing which happens before the init of the widget.

);

placesAutocomplete.on('change', opts => {
this.placesAutocomplete.on('change', opts => {
const {
suggestion: {
latlng: { lat, lng },
value,
},
} = opts;

this.state.position = `${lat},${lng}`;
this.state.query = value;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than duplicate the source of truth for the values why doesn't read them directly from the helper & placesAutocomplete?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not the query you're looking for. It's actually the value for searching for values in places, which is nowhere in the main search state.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes but since you have access to the Places instance you can have access to it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although you can simplify the internal state by removing the position information, you cannot make it completely disappear, as the getVal method from the placesAutocomplete instance will yield stale data.

the placesAutocomplete.on('change', () => {}) is triggered before the update of the value of the input, and so is getWidgetState. So placesAutocomplete.getVal will yield the previous input value, instead of the new one.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok thanks for the update!


helper
.setQueryParameter('insideBoundingBox')
.setQueryParameter('aroundLatLng', `${lat},${lng}`)
.setQueryParameter('aroundLatLng', this.state.position)
.search();
});

placesAutocomplete.on('clear', () => {
this.placesAutocomplete.on('clear', () => {
this.state.position = undefined;
this.state.query = undefined;

helper
.setQueryParameter('insideBoundingBox')
.setQueryParameter('aroundLatLng', this.defaultPosition)
.search();
});
}

getWidgetSearchParameters(searchParameters, { uiState }) {
if (!uiState.places) {
this.placesAutocomplete.setVal('');
return searchParameters;
}

const { query, position } = uiState.places;

this.state = uiState.places;
this.placesAutocomplete.setVal(query || '');

return searchParameters
.setQueryParameter('insideBoundingBox')
.setQueryParameter('aroundLatLng', position);
}

getWidgetState(uiState, { searchParameters }) {
if (
uiState.places &&
this.state.query === uiState.places.query &&
searchParameters.aroundLatLng === uiState.places.position
) {
return uiState;
}

if (
searchParameters.aroundLatLng === undefined &&
this.state.query === undefined
) {
const newUiState = Object.assign({}, uiState);
delete newUiState.places;
return newUiState;
}

return {
...uiState,
places: {
query: this.state.query,
position: searchParameters.aroundLatLng,
},
};
}
}

/**
Expand Down
Loading