Merge pull request #867 from sharetribe/add-sessiontoken-and-sparse-fields

Add sessiontoken and sparse fields
This commit is contained in:
Vesa Luusua 2018-07-19 14:20:39 +03:00 committed by GitHub
commit f97cf4827a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 7 deletions

View file

@ -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.

View file

@ -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);
@ -266,7 +270,11 @@ 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,
@ -274,6 +282,7 @@ class LocationAutocompleteInput extends Component {
selectedPlaceId: placeId,
selectedPlace: place,
});
this.autocompleteSessionToken = null;
})
.catch(e => {
// eslint-disable-next-line no-console
@ -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);

View file

@ -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}"`)
@ -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 {