Skip to content

Commit

Permalink
Merge pull request FaridSafi#943 from rojiphil/new-places-api
Browse files Browse the repository at this point in the history
New places api
  • Loading branch information
FaridSafi authored Oct 4, 2024
2 parents ef10738 + c7d9bab commit 313ccf8
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 24 deletions.
11 changes: 11 additions & 0 deletions GooglePlacesAutocomplete.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -286,11 +286,15 @@ interface GooglePlaceData {
interface Point {
lat: number;
lng: number;
latitude: number;
longitude: number;
}

interface AddressComponent {
long_name: string;
short_name: string;
longText: string;
shortText: string;
types: PlaceType[];
}

Expand Down Expand Up @@ -323,6 +327,11 @@ interface GooglePlaceDetail {
url: string;
utc_offset: number;
vicinity: string;
// New Places API parameters
addressComponents: AddressComponent[];
adrFormatAddress: string;
formattedAddress: string;
location: Point;
}

/** @see https://developers.google.com/places/web-service/autocomplete */
Expand Down Expand Up @@ -431,6 +440,8 @@ interface GooglePlacesAutocompleteProps {
/** text input props */
textInputProps?: TextInputProps | Object;
timeout?: number;
isNewPlacesAPI?: boolean;
fields?: string;
}

export type GooglePlacesAutocompleteRef = {
Expand Down
119 changes: 97 additions & 22 deletions GooglePlacesAutocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import debounce from 'lodash.debounce';
import PropTypes from 'prop-types';
import Qs from 'qs';
import { v4 as uuidv4 } from 'uuid';
import React, {
forwardRef,
useMemo,
Expand Down Expand Up @@ -159,7 +160,7 @@ export const GooglePlacesAutocomplete = forwardRef((props, ref) => {
const [listLoaderDisplayed, setListLoaderDisplayed] = useState(false);

const inputRef = useRef();

const [sessionToken, setSessionToken] = useState(uuidv4());
useEffect(() => {
setUrl(getRequestUrl(props.requestUrl));
}, [getRequestUrl, props.requestUrl]);
Expand Down Expand Up @@ -281,10 +282,14 @@ export const GooglePlacesAutocomplete = forwardRef((props, ref) => {

if (request.status === 200) {
const responseJSON = JSON.parse(request.responseText);

if (responseJSON.status === 'OK') {
if (
responseJSON.status === 'OK' ||
(props.isNewPlacesAPI && responseJSON.id)
) {
// if (_isMounted === true) {
const details = responseJSON.result;
const details = props.isNewPlacesAPI
? responseJSON
: responseJSON.result;
_disableRowLoaders();
_onBlur();

Expand Down Expand Up @@ -322,16 +327,29 @@ export const GooglePlacesAutocomplete = forwardRef((props, ref) => {
}
};

request.open(
'GET',
`${url}/place/details/json?` +
Qs.stringify({
key: props.query.key,
placeid: rowData.place_id,
language: props.query.language,
...props.GooglePlacesDetailsQuery,
}),
);
if (props.isNewPlacesAPI) {
request.open(
'GET',
`${url}/v1/places/${rowData.place_id}?` +
Qs.stringify({
key: props.query.key,
sessionToken,
fields: props.fields,
}),
);
setSessionToken(uuidv4());
} else {
request.open(
'GET',
`${url}/place/details/json?` +
Qs.stringify({
key: props.query.key,
placeid: rowData.place_id,
language: props.query.language,
...props.GooglePlacesDetailsQuery,
}),
);
}

request.withCredentials = requestShouldUseWithCredentials();
setRequestHeaders(request, getRequestHeaders(props.requestUrl));
Expand Down Expand Up @@ -419,6 +437,29 @@ export const GooglePlacesAutocomplete = forwardRef((props, ref) => {
return results;
};

const _filterResultsByPlacePredictions = (unfilteredResults) => {
const results = [];
for (let i = 0; i < unfilteredResults.length; i++) {
if (unfilteredResults[i].placePrediction) {
results.push({
description: unfilteredResults[i].placePrediction.text?.text,
place_id: unfilteredResults[i].placePrediction.placeId,
reference: unfilteredResults[i].placePrediction.placeId,
structured_formatting: {
main_text:
unfilteredResults[i].placePrediction.structuredFormat?.mainText
?.text,
secondary_text:
unfilteredResults[i].placePrediction.structuredFormat
?.secondaryText?.text,
},
types: unfilteredResults[i].placePrediction.types ?? [],
});
}
}
return results;
};

const _requestNearby = (latitude, longitude) => {
_abortRequests();

Expand Down Expand Up @@ -524,6 +565,7 @@ export const GooglePlacesAutocomplete = forwardRef((props, ref) => {
setListLoaderDisplayed(false);
if (request.status === 200) {
const responseJSON = JSON.parse(request.responseText);

if (typeof responseJSON.predictions !== 'undefined') {
// if (_isMounted === true) {
const results =
Expand All @@ -538,6 +580,14 @@ export const GooglePlacesAutocomplete = forwardRef((props, ref) => {
setDataSource(buildRowsFromResults(results, text));
// }
}
if (typeof responseJSON.suggestions !== 'undefined') {
const results = _filterResultsByPlacePredictions(
responseJSON.suggestions,
);

_results = results;
setDataSource(buildRowsFromResults(results, text));
}
if (typeof responseJSON.error_message !== 'undefined') {
if (!props.onFail)
console.warn(
Expand All @@ -556,18 +606,39 @@ export const GooglePlacesAutocomplete = forwardRef((props, ref) => {
setStateText(props.preProcess(text));
}

request.open(
'GET',
`${url}/place/autocomplete/json?input=` +
encodeURIComponent(text) +
'&' +
Qs.stringify(props.query),
);
if (props.isNewPlacesAPI) {
const keyQueryParam = props.query.key
? '?' +
Qs.stringify({
key: props.query.key,
})
: '';
request.open('POST', `${url}/v1/places:autocomplete${keyQueryParam}`);
} else {
request.open(
'GET',
`${url}/place/autocomplete/json?input=` +
encodeURIComponent(text) +
'&' +
Qs.stringify(props.query),
);
}

request.withCredentials = requestShouldUseWithCredentials();
setRequestHeaders(request, getRequestHeaders(props.requestUrl));

request.send();
if (props.isNewPlacesAPI) {
const { key, locationbias, types, ...rest } = props.query;
request.send(
JSON.stringify({
input: text,
sessionToken,
...rest,
}),
);
} else {
request.send();
}
} else {
_results = [];
setDataSource(buildRowsFromResults([]));
Expand Down Expand Up @@ -942,6 +1013,8 @@ GooglePlacesAutocomplete.propTypes = {
textInputHide: PropTypes.bool,
textInputProps: PropTypes.object,
timeout: PropTypes.number,
isNewPlacesAPI: PropTypes.bool,
fields: PropTypes.string,
};

GooglePlacesAutocomplete.defaultProps = {
Expand Down Expand Up @@ -986,6 +1059,8 @@ GooglePlacesAutocomplete.defaultProps = {
textInputHide: false,
textInputProps: {},
timeout: 20000,
isNewPlacesAPI: false,
fields: '*',
};

GooglePlacesAutocomplete.displayName = 'GooglePlacesAutocomplete';
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-native-google-places-autocomplete",
"version": "2.5.6",
"version": "2.5.7",
"description": "Customizable Google Places autocomplete component for iOS and Android React-Native apps",
"main": "GooglePlacesAutocomplete.js",
"types": "GooglePlacesAutocomplete.d.ts",
Expand Down Expand Up @@ -31,7 +31,8 @@
"dependencies": {
"lodash.debounce": "^4.0.8",
"prop-types": "^15.7.2",
"qs": "~6.9.1"
"qs": "~6.9.1",
"uuid": "^10.0.0"
},
"devDependencies": {
"@react-native-community/eslint-config": "2.0.0",
Expand Down

0 comments on commit 313ccf8

Please sign in to comment.