Algolia Places
On this page
Overview
Algolia Places provides a fast, distributed, and easy way to use an address search autocomplete JavaScript library on your website. There is no built-in solution to integrate Algolia Places with React InstantSearch. But you can create a custom widget that will wrap Places. In this guide we will see how we can create a custom Places widget that interacts with the GeoSearch
widget of React InstantSearch. You can find the complete source code of the example on GitHub.
Connector
The first step is to build our custom widget on top of Algolia Places, which involves creating a custom connector that will link Places to the React InstantSearch context. The refine
function stores the value from the Places input under the aroundLatLng
attribute. Then to apply our value to our search we leverage the aroundLatLng search parameter. At the same time we also clear insideBoundingBox currently applied because those two parameters are not “compatible”. When a bounding box is set, the aroundLatLng
parameter is ignored.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import { createConnector } from 'react-instantsearch-dom';
export default createConnector({
displayName: 'AlgoliaPlaces',
getProvidedProps() {
return {};
},
refine(props, searchState, nextValue) {
return {
...searchState,
aroundLatLng: nextValue,
boundingBox: {},
};
},
getSearchParameters(searchParameters, props, searchState) {
const currentRefinement =
searchState.aroundLatLng || props.defaultRefinement;
return searchParameters
.setQueryParameter('insideBoundingBox')
.setQueryParameter(
'aroundLatLng',
`${currentRefinement.lat}, ${currentRefinement.lng}`
);
},
});
Widget
The second step (to build our custom widget on top of Algolia Places) is to create a React wrapper around the Algolia Places JS library. This wrapper component will also be wrapped by the connector that we created above. Keep in mind that it’s a very simple example. The widget doesn’t support all the Algolia Places options. Feel free to adapt it to your own needs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import React, { Component } from 'react';
import places from 'places.js';
import connect from './connector';
class Places extends Component {
createRef = c => (this.element = c);
componentDidMount() {
const { refine, defaultRefinement } = this.props;
const autocomplete = places({
container: this.element,
// Algolia Places options
});
autocomplete.on('change', event => {
refine(event.suggestion.latlng);
});
autocomplete.on('clear', () => {
refine(defaultRefinement);
});
}
render() {
return (
<div style={{ marginBottom: 20 }}>
<input
ref={this.createRef}
type="search"
id="address-input"
placeholder="Where are we going?"
/>
</div>
);
}
}
export default connect(Places);
Usage
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import algoliasearch from 'algoliasearch/lite';
import { InstantSearch } from 'react-instantsearch-dom';
import Places from './widget';
const searchClient = algoliasearch(
'latency',
'6be0576ff61c053d5f9a3225e2a90f76'
);
const App = () => (
<InstantSearch indexName="airports" searchClient={searchClient}>
<Places
defaultRefinement={{
lat: 37.7793,
lng: -122.419
}}
/>
</InstantSearch>
);
You can find the complete source code of the example on GitHub.