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

feat(controlled-search): expose search method in places.js #659

Merged
merged 3 commits into from
Feb 25, 2019
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
20 changes: 18 additions & 2 deletions docs/source/examples.html.md.erb
Original file line number Diff line number Diff line change
Expand Up @@ -210,11 +210,27 @@ See the documentation about the [placesAutocompleteDataset function](documentati

### Nearby City Search

**Concepts:** type parameter, aroundLatLngViaIP, aroundPrecision, Places API Client.
**Concepts:** type parameter, aroundLatLngViaIP, aroundPrecision, programmatic search.

In this section, we will see how you can _emulate_ reverse geocoding to find city closest to a user using the Places API Client.

<%= partial '/partials/examples/reverse-city-search/demo', locals: config[:credentials][:documentation] %>
<%= partial '/partials/examples/reverse-city-search/demo_places', locals: config[:credentials][:documentation] %>

```html
<%= partial '/partials/examples/reverse-city-search/code_places', locals: config[:credentials][:placeholder] %>
```

**Note:** This is not a reverse geocoding API, and it is still bound by the ranking used for search, which means that in some cases large close-by cities can be promoted over a more closely located city.

### Using an API client

In some cases, you may not want to tie your Places search to an input, but rather access it only programmatically.

In these cases, you can use the regular JavaScript API Client, or the api client in your preferred language. You can head to the [API Clients page](api-clients.html) to see which api clients support Places.

For instance, here we will rewrite the previous example using the JS api client instead.

<%= partial '/partials/examples/reverse-city-search/code', locals: config[:credentials][:documentation] %>

```html
<%= partial '/partials/examples/reverse-city-search/code', locals: config[:credentials][:placeholder] %>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<div>
<strong>Searching around: </strong>
<div id="reverse-city"></div>
<div id="api-client-reverse-city"></div>
</div>

<script src="https://cdn.jsdelivr.net/algoliasearch/3/algoliasearch.min.js"></script>
Expand All @@ -27,7 +27,7 @@ placesClient.search({
var country = hits[0].country;
var formattedCity = locale_names[0] + ', ' + country;

var infoElt = document.querySelector("#reverse-city");
var infoElt = document.querySelector("#api-client-reverse-city");
infoElt.textContent = formattedCity;
});
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<div>
<strong>Searching around: </strong>
<input type="search" id="reverse-city" placeholder="What's your favorite city?"></div>
</div>

<%= javascript_include_tag config[:places_lib_url] %>
<script>
var placesAutocomplete = places({
appId: '<%= app_id %>',
apiKey: '<%= api_key %>',
container: document.querySelector('#reverse-city')
}).configure({
type: 'city',
hitsPerPage: 1,
aroundLatLngViaIP: true
});

placesAutocomplete.search().then(function(suggestions) {
if (!suggestions[0]) {
return;
}

var name = suggestions[0].name;
var country = suggestions[0].country;
var formattedCity = locale_names[0] + ', ' + country;

var infoElt = document.querySelector("#reverse-city");
infoElt.value = formattedCity;
});
</script>
46 changes: 0 additions & 46 deletions docs/source/partials/examples/reverse-city-search/_demo.html.erb

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<div>
<p>When constructing a search UI using InstantSearch, you may want to filter your dataset to only display some of your products based on the distance to the end user. This is usually done using the aroundLatLngViaIP filter, or aroundLatLng filter if you have access to precise geolocation information. However geographical filters are hard to interpret when displayed in raw format, as noone really knows where the coordinates <span id="coords"><code>48.8566, 2.34287</code></span> are.</p>

<p>Using Places, you can do a query to find the city in which your user is located and display that city name instead of a geolocation.</p>
</div>

<p><strong>Example:</strong></p>

<div>
<strong>Searching around: </strong>
<input type="search" id="reverse-city" placeholder="Your favorite city" />
</div>

<%= javascript_include_tag config[:places_lib_url] %>
<script>
var placesAutocomplete = places({
appId: '<%= app_id %>',
apiKey: '<%= api_key %>',
container: document.querySelector('#reverse-city')
}).configure({
type: 'city',
hitsPerPage: 5,
aroundLatLngViaIP: true,
debug: true
});

placesAutocomplete.search().then(function(suggestions) {
if (!suggestions[0]) {
return;
}

var name = suggestions[0].name;
var country = suggestions[0].country;
var latlng = suggestions[0].latlng;
var formattedCity = name + ', ' + country;

var coordElt = document.querySelector("#coords");
var lat = latlng.lat;
var lng = latlng.lng;
coordElt.innerHTML = '<code>' + lat + ', ' + lng + '</code>';

var infoElt = document.querySelector("#reverse-city");
infoElt.value = formattedCity;
});

placesAutocomplete.on('change', (response) => {
var suggestion = response.suggestion;
var latlng = suggestion.latlng;
var coordElt = document.querySelector("#coords");
var lat = latlng.lat;
var lng = latlng.lng;
coordElt.innerHTML = '<code>' + lat + ', ' + lng + '</code>';
});
</script>
5 changes: 5 additions & 0 deletions src/places.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,11 @@ export default function places(options) {

placesInstance.autocomplete = autocompleteInstance;

placesInstance.search = (query = '') =>
new Promise(resolve => {
autocompleteDataset.source(query, resolve);
});

placesInstance.configure = configuration => {
const safeConfig = Object.assign({}, configuration);

Expand Down
22 changes: 22 additions & 0 deletions src/places.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -430,4 +430,26 @@ describe('places', () => {
language: 'de',
});
});

it('has a search method which calls autocomplete.source', () => {
autocomplete.mockClear();
const container = document
.querySelector('body')
.appendChild(document.createElement('input'));

const searchMock = jest.fn();
createAutocompleteDataset.mockImplementation(() => ({
source: searchMock,
other: 'autocompleteDataset',
}));

const placesInstance = places({
container,
autocompleteOptions: { option: 'value' },
});

placesInstance.search('some Query');

expect(searchMock.mock.calls[0][0]).toEqual('some Query');
});
});