Skip to content

Commit

Permalink
Merge pull request #867 from sharetribe/add-sessiontoken-and-sparse-f…
Browse files Browse the repository at this point in the history
…ields

Add sessiontoken and sparse fields
  • Loading branch information
Gnito authored Jul 19, 2018
2 parents 32d9955 + aeac2cd commit f97cf48
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 7 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ way to update this template, but currently, we follow a pattern:
---

## Upcoming version

* [change] Use sessionTokens and fields for Autocomplete calls to Google Maps.
This is a reaction to pricing change of Google Maps APIs.
[#867](https://github.com/sharetribe/flex-template-web/pull/867)
* [change] Change TransactionPage state management in loadData.
[#863](https://github.com/sharetribe/flex-template-web/pull/863), [#865](https://github.com/sharetribe/flex-template-web/pull/865) & [#866](https://github.com/sharetribe/flex-template-web/pull/866)
* [fix] Fix submit button state on contact details page.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,10 @@ class LocationAutocompleteInput extends Component {
// Ref to the input element.
this.input = null;

// Current sessionToken used to combine autocomplete calls with place details call
// This reduces Google Maps pricing.
this.autocompleteSessionToken = null;

this.changeHighlight = this.changeHighlight.bind(this);
this.selectItem = this.selectItem.bind(this);
this.selectItemIfNoneSelected = this.selectItemIfNoneSelected.bind(this);
Expand Down Expand Up @@ -266,14 +270,19 @@ class LocationAutocompleteInput extends Component {
selectedPlace: null,
});

getPlaceDetails(placeId)
this.autocompleteSessionToken =
this.autocompleteSessionToken || new window.google.maps.places.AutocompleteSessionToken();
const sessionToken = this.autocompleteSessionToken;

getPlaceDetails(placeId, sessionToken)
.then(place => {
this.props.input.onChange({
search: prediction.description,
predictions: [],
selectedPlaceId: placeId,
selectedPlace: place,
});
this.autocompleteSessionToken = null;
})
.catch(e => {
// eslint-disable-next-line no-console
Expand All @@ -298,7 +307,12 @@ class LocationAutocompleteInput extends Component {
throw new Error('Google Maps API must be loaded for LocationAutocompleteInput');
}
const onChange = this.props.input.onChange;
getPlacePredictions(search)

this.autocompleteSessionToken =
this.autocompleteSessionToken || new window.google.maps.places.AutocompleteSessionToken();
const sessionToken = this.autocompleteSessionToken;

getPlacePredictions(search, sessionToken)
.then(results => {
const { search: currentSearch } = currentValue(this.props);

Expand Down
15 changes: 11 additions & 4 deletions src/util/googleMaps.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,21 @@ const placeCountry = place => {
*
* @param {String} placeId - ID for a place received from the
* autocomplete service
* @param {String} sessionToken - token to tie different autocomplete character searches together
* with getPlaceDetails call
*
* @return {Promise<util.propTypes.place>} Promise that
* resolves to the detailed place, rejects if the request failed
*/
export const getPlaceDetails = placeId =>
export const getPlaceDetails = (placeId, sessionToken) =>
new Promise((resolve, reject) => {
const serviceStatus = window.google.maps.places.PlacesServiceStatus;
const el = document.createElement('div');
const service = new window.google.maps.places.PlacesService(el);
const fields = ['address_component', 'formatted_address', 'geometry', 'place_id'];
const sessionTokenMaybe = sessionToken ? { sessionToken } : {};

service.getDetails({ placeId }, (place, status) => {
service.getDetails({ placeId, fields, ...sessionTokenMaybe }, (place, status) => {
if (status !== serviceStatus.OK) {
reject(
new Error(`Could not get details for place id "${placeId}", error status was "${status}"`)
Expand All @@ -71,16 +75,19 @@ const predictionSuccessful = status => {
* Get place predictions for the given search
*
* @param {String} search - place name or address to search
* @param {String} sessionToken - token to tie different autocomplete character searches together
* with getPlaceDetails call
*
* @return {Promise<{ search, predictions[] }>} - Promise of an object
* with the original search query and an array of
* `google.maps.places.AutocompletePrediction` objects
*/
export const getPlacePredictions = search =>
export const getPlacePredictions = (search, sessionToken) =>
new Promise((resolve, reject) => {
const service = new window.google.maps.places.AutocompleteService();
const sessionTokenMaybe = sessionToken ? { sessionToken } : {};

service.getPlacePredictions({ input: search }, (predictions, status) => {
service.getPlacePredictions({ input: search, ...sessionTokenMaybe }, (predictions, status) => {
if (!predictionSuccessful(status)) {
reject(new Error(`Prediction service status not OK: ${status}`));
} else {
Expand Down

0 comments on commit f97cf48

Please sign in to comment.