Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save WillMayger/6db35a1678c26efe7a6e19921a8a312b to your computer and use it in GitHub Desktop.
Save WillMayger/6db35a1678c26efe7a6e19921a8a312b to your computer and use it in GitHub Desktop.
// Script tag to include in <head>:
<script
type="text/javascript"
src="//maps.googleapis.com/maps/api/js?key=YOUR_API_KEY_GOES_HERE&language=en&libraries=places"
></script>
import React, { useState, useEffect } from "react"
// Async google places autocomplete function
export const googleAutocomplete = async text =>
new Promise((resolve, reject) => {
if (!text) {
return reject("Need valid text input")
}
// for use in things like GatsbyJS where the html is generated first
if (typeof window === "undefined") {
return reject("Need valid window object")
}
try {
new window.google.maps.places.AutocompleteService().getPlacePredictions(
{ input: text, componentRestrictions: { country: "gb" } },
resolve
)
} catch (e) {
reject(e)
}
})
// React component that uses the auto complete function
export function PredictionsOnFormSubmission() {
const [searchValue, setSearchValue] = useState("")
const [predictions, setPredictions] = useState([])
const handleSubmit = async e => {
e.preventDefault()
const results = await googleAutocomplete(searchValue)
if (results) {
setPredictions(results)
}
}
return (
<>
<form onSubmit={handleSubmit}>
<input
name="predictionSearch"
value={searchValue}
onChange={e => setSearchValue(e.target.value)}
/>
<button type="submit">Search</button>
</form>
<img
src="https://developers.google.com/maps/documentation/images/powered_by_google_on_white.png"
alt="Powered by Google"
/>
{predictions?.map(prediction => (
<p key={prediction?.place_id}>
{prediction?.structured_formatting?.main_text || "Not found"}
</p>
))}
</>
)
}
// Google places autocomplete react hook
import { useState, useEffect } from 'react'
// the function we just created
import { googleAutocomplete } from './google-autocomplete'
export function usePlacesAutocomplete(text = "", debounceTimeout = 400) {
const [predictions, setPredictions] = useState([])
useEffect(() => {
const handleDebounce = setTimeout(async () => {
try {
if (!text) {
return
}
const nextPredictions = await googleAutocomplete(text)
setPredictions(nextPredictions)
} catch (e) {
console.error(e)
}
}, debounceTimeout)
return () => {
clearTimeout(handleDebounce)
}
}, [text, debounceTimeout])
return predictions
}
// Using the react hook in a function example
export function PredictionsOnInputChange() {
const [selectedPrediction, setSelectedPrediction] = useState(null)
const [searchValue, setSearchValue] = useState("")
const predictions = usePlacesAutocomplete(searchValue)
const handlePredictionSelection = (e, prediction) => {
e.preventDefault()
setSelectedPrediction(prediction)
}
return (
<>
<form>
<input
name="predictionSearch"
value={searchValue}
onChange={e => setSearchValue(e.target.value)}
/>
<img
src="https://developers.google.com/maps/documentation/images/powered_by_google_on_white.png"
alt="Powered by Google"
/>
<ul>
{predictions?.map(prediction => (
<li key={prediction?.place_id}>
<button
onClick={e => handlePredictionSelection(e, prediction)}
onKeyDown={e => handlePredictionSelection(e, prediction)}
>
{prediction?.structured_formatting?.main_text || "Not found"}
</button>
</li>
))}
</ul>
<h3>You searched for: {searchValue}</h3>
<h3>
You selected:{" "}
{selectedPrediction?.structured_formatting?.main_text || "None"}
</h3>
</form>
</>
)
}
@michaelchen753
Copy link

Well done! mate

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment