diff --git a/README.md b/README.md index a7bb7c06..380abc95 100644 --- a/README.md +++ b/README.md @@ -319,6 +319,12 @@ Default: `text` The value for the `type` attribute on the html input element. Can be either `text` or `search`. +### handleGeocodingError +Type: `Function` +Default `undefined` + +An optional error handler that can process the error returned by the [`Geocoder.geocode`](https://developers.google.com/maps/documentation/javascript/reference/geocoder#Geocoder-Methods) API. + #### Others All [allowed attributes for `input[type="text"]`](https://github.com/ubilabs/react-geosuggest/blob/master/src/filter-input-attributes.ts#L4) diff --git a/package-lock.json b/package-lock.json index f6f1d497..a100e200 100644 --- a/package-lock.json +++ b/package-lock.json @@ -529,10 +529,10 @@ "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", "dev": true }, - "@types/googlemaps": { - "version": "3.39.13", - "resolved": "https://registry.npmjs.org/@types/googlemaps/-/googlemaps-3.39.13.tgz", - "integrity": "sha512-R/k5WKe8zQHo9oFRINuX/1haKYRkKEfItnBGrSjspbXXITakRdsj6daQIdL1+Pt84lnzduWurxNA5k0fgPMQUg==", + "@types/google.maps": { + "version": "3.45.2", + "resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.45.2.tgz", + "integrity": "sha512-3hKhaLt4EcKzssjmpIH8M12tN8WHp/gz7lh+85NdwXGtGSAjtiOEG4st9XdvaZkUHtlNaiAP2PlDbkNnNmD2NQ==", "dev": true }, "@types/jsdom": { diff --git a/package.json b/package.json index 5299410f..9ce0bc03 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "@rollup/plugin-replace": "^2.3.3", "@types/chai": "^4.2.12", "@types/classnames": "^2.2.10", - "@types/googlemaps": "^3.39.13", + "@types/google.maps": "^3.45.2", "@types/jsdom": "^16.2.4", "@types/lodash.debounce": "^4.0.6", "@types/mocha": "^8.0.3", diff --git a/src/Geosuggest.tsx b/src/Geosuggest.tsx index ea3cba42..87f11e5a 100644 --- a/src/Geosuggest.tsx +++ b/src/Geosuggest.tsx @@ -542,7 +542,7 @@ export default class extends React.Component { this.placesService.getDetails(options, (results, status) => { if (status === this.googleMaps.places.PlacesServiceStatus.OK) { const gmaps = results; - const location = (gmaps.geometry && + const location = (gmaps?.geometry && gmaps.geometry.location) as google.maps.LatLng; const suggest = { ...suggestToGeocode, @@ -560,35 +560,41 @@ export default class extends React.Component { } }); } else { + const country = Array.isArray(this.props.country) + ? this.props.country[0] + : this.props.country; const options: google.maps.GeocoderRequest = { address: suggestToGeocode.label, bounds: this.props.bounds, - componentRestrictions: this.props.country - ? {country: this.props.country} - : // eslint-disable-next-line no-undefined - undefined, + componentRestrictions: {country}, location: this.props.location }; - this.geocoder.geocode(options, (results, status) => { - if (status === this.googleMaps.GeocoderStatus.OK) { - const gmaps = results[0]; - const location = (gmaps.geometry && - gmaps.geometry.location) as google.maps.LatLng; - const suggest = { - ...suggestToGeocode, - gmaps, - location: { - lat: location.lat(), - lng: location.lng() - } - }; + this.geocoder + .geocode(options, (results, status) => { + if (status === this.googleMaps.GeocoderStatus.OK) { + const gmaps = results?.[0]; + const location = (gmaps?.geometry && + gmaps.geometry.location) as google.maps.LatLng; + const suggest = { + ...suggestToGeocode, + gmaps, + location: { + lat: location.lat(), + lng: location.lng() + } + }; - if (this.props.onSuggestSelect) { - this.props.onSuggestSelect(suggest); + if (this.props.onSuggestSelect) { + this.props.onSuggestSelect(suggest); + } } - } - }); + }) + ?.catch((error) => { + if (this.props.handleGeocodingError) { + this.props.handleGeocodingError(error); + } + }); } } diff --git a/src/types/location.d.ts b/src/types/location.d.ts index 2e762c8c..fe2f1da0 100644 --- a/src/types/location.d.ts +++ b/src/types/location.d.ts @@ -8,6 +8,9 @@ type ILocation = ISuggest & { lat: number; lng: number; }; - readonly gmaps?: google.maps.GeocoderResult | google.maps.places.PlaceResult; + readonly gmaps?: + | google.maps.GeocoderResult + | google.maps.places.PlaceResult + | null; }; export default ILocation; diff --git a/src/types/props.d.ts b/src/types/props.d.ts index 12e596ed..7059ca3e 100644 --- a/src/types/props.d.ts +++ b/src/types/props.d.ts @@ -58,4 +58,5 @@ export default interface IProps { readonly minLength?: number; readonly placeDetailFields?: string[] | null; readonly inputType?: string; + readonly handleGeocodingError?: (error: Error) => void; } diff --git a/test/fixtures/predictions.ts b/test/fixtures/predictions.ts index 02a6ed18..b57cd103 100644 --- a/test/fixtures/predictions.ts +++ b/test/fixtures/predictions.ts @@ -4,7 +4,6 @@ export default function predictions(): google.maps.places.AutocompletePrediction return [ { description: 'New York, NY, United States', - id: '7eae6a016a9c6f58e2044573fb8f14227b6e1f96', matched_substrings: [ { length: 2, @@ -12,7 +11,6 @@ export default function predictions(): google.maps.places.AutocompletePrediction } ], place_id: 'ChIJOwg_06VPwokRYv534QaPC8g', - reference: '...', structured_formatting: { main_text: 'New York, NY, United States', main_text_matched_substrings: [ @@ -41,7 +39,6 @@ export default function predictions(): google.maps.places.AutocompletePrediction }, { description: 'New York, IA, United States', - id: '329cb7144660f29514f351db26cef864634f748a', matched_substrings: [ { length: 2, @@ -49,7 +46,6 @@ export default function predictions(): google.maps.places.AutocompletePrediction } ], place_id: 'ChIJD_qB3F8X6YcRDraFbXmLUD4', - reference: '...', structured_formatting: { main_text: 'New York, IA, United States', main_text_matched_substrings: [ @@ -78,7 +74,6 @@ export default function predictions(): google.maps.places.AutocompletePrediction }, { description: 'New York, United States', - id: '349c7fc49816ce54bb586cf8fa2cd79b255746b3', matched_substrings: [ { length: 2, @@ -86,7 +81,6 @@ export default function predictions(): google.maps.places.AutocompletePrediction } ], place_id: 'ChIJqaUj8fBLzEwRZ5UY3sHGz90', - reference: '...', structured_formatting: { main_text: 'New York, United States', main_text_matched_substrings: [ @@ -111,7 +105,6 @@ export default function predictions(): google.maps.places.AutocompletePrediction }, { description: 'New Jersey, United States', - id: '10806aba84cf3520ebd83c6a3f749bad23c4e2e6', matched_substrings: [ { length: 2, @@ -119,7 +112,6 @@ export default function predictions(): google.maps.places.AutocompletePrediction } ], place_id: 'ChIJn0AAnpX7wIkRjW0_-Ad70iw', - reference: '...', structured_formatting: { main_text: 'New Jersey, United States', main_text_matched_substrings: [ @@ -144,7 +136,6 @@ export default function predictions(): google.maps.places.AutocompletePrediction }, { description: 'Newark, NJ, United States', - id: 'c71040d6268e495203b4ca7ca4299893601f63fc', matched_substrings: [ { length: 2, @@ -152,7 +143,6 @@ export default function predictions(): google.maps.places.AutocompletePrediction } ], place_id: 'ChIJHQ6aMnBTwokRc-T-3CrcvOE', - reference: '...', structured_formatting: { main_text: 'Newark, NJ, United States', main_text_matched_substrings: [