DEV Community

Cover image for How to use Google Maps Places Autocomplete with React JS
Abdeldjalil Hachimi
Abdeldjalil Hachimi

Posted on

How to use Google Maps Places Autocomplete with React JS

Hello everyone, I hope you are doing.
today I would like to explain how to use google maps places autocomplete without any libraries or npm's packages and headache πŸ˜‚ so that let's get started

Setup and Installing React JS

let's do it very quick just follow the steps I suppose you have some background how to do so

Image description

Image description

3.

Image description

4.

Image description

5.

Image description

6.

Image description

7.
Image description

the first thing you have to do in index.html after setup the project is that



<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title> React js with Google Map AutoComplete </title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.jsx"></script>

**    <script
      src="https://maps.googleapis.com/maps/api/js?key="your-api-key"&libraries=places&callback=initMap"
      async
    ></script>**
  </body>
</html>


Enter fullscreen mode Exit fullscreen mode

after that create a component for Map using the library @react-google-maps/api



import React, { useState, useCallback } from 'react'
import { GoogleMap, Marker, useJsApiLoader } from '@react-google-maps/api'


const mapStyle = { 
    height: '300px', 
    width: '100%'
 }



const Map = () => {
    const DEFAULT_ZOOM = 5
    const { isLoaded } = useJsApiLoader({
        id: 'google-map-script',
        googleMapsApiKey: "your-api-key"
    })

    const [map, setMap] = React.useState(null)
    const [markerPosition, setMarkerPosition] = useState({
        lat: 28.0289837,
        lng: 1.6666663,
      })

    const [defaultLocation, setDefaultLocation] = useState({
        lat: 28.0289837,
        lng: 1.6666663,
      })

    const onLoad = useCallback((map)=> {
        const bounds = new window.google.maps.LatLngBounds({
            lat: 28.0289837,
            lng: 1.6666663,
          });
        map.fitBounds(bounds);
        setMap(map)
      }, [])

      const onUnmount = useCallback(() =>{
        setMap(null)
      }, [])


    const handelClickOnMap  = ()=> {

      }
  return (
    <div>
     {
        isLoaded ? (
        <GoogleMap
        onLoad={onLoad}
        center={defaultLocation}
        zoom={DEFAULT_ZOOM}
        mapContainerStyle={mapStyle}
        onClick={handelClickOnMap}
        onUnmount={onUnmount}
        >
           <Marker position={markerPosition} />
        </GoogleMap>
        ) : <></>
     }  
   </div>
  )
}

export default Map


Enter fullscreen mode Exit fullscreen mode

after that import Map component in App.jsx file
and now let's create our input for search for places with autocomplete (suggestion places)



    import { useRef, useState } from 'react'
import MapView from './components/Map'


function App() {

  const inputRef = useRef()
  const inputStyle= {
    boxShadow: 'inset 0 0 10px #eee !important',
    border: '2px solid #eee',
    width: '456px',
    height: '40px',
    marginLeft: '16px',
    borderRadius: '20px',
    fontWeight: '300 !important',
    outline: 'none',
    padding: '10px 20px',
    marginBottom: '10px',
  }


  const autoComplete = new window.google.maps.places.Autocomplete(
    inputRef.current,
  )


  autoComplete.addListener('place_changed', () => {
    const place = autoComplete.getPlace()
    if (!place.geometry || !place.geometry.location) {
      // User entered the name of a Place that was not suggested and
      // pressed the Enter key, or the Place Details request failed.
        alert("this location not available")
    }
    if (place.geometry.viewport || place.geometry.location) {
        // do something
        console.log(place.geometry.location)
    }
  })
  return (
    <div className="App">
        <label >Location</label>
        <input
          placeholder='type your location'
          ref={inputRef}
          style={inputStyle}
        />
      <MapView/>
    </div>
  )
}

export default App



Enter fullscreen mode Exit fullscreen mode

and voila here it is the result 😁

Image description

Finally, Thank you for reading this post I will glad to hear your feedback.

Github repo for code source

https://github.com/abdeldjalilhachimi/react-google-map-autocomplete

Top comments (7)

Collapse
 
boira profile image
boira

Hi,

thank you for your post, this has saved me many hours of work!

I have copy-pasted your code and it seems to be working fine, but I can see that too many requests are send when I type someting in the autocomplete imput:

For example, if I want to find "fuente" (fountain, in Spanish), I type an F, then a U, then a E etc... Only with 4-5 characters I can see 150 requests to the API. Do you know how to fix that?

Thanks!

Collapse
 
abdeldjalilhachimi profile image
Abdeldjalil Hachimi

@boira Well in this case you can use debounce to delay sending a request when the user typing and that's it

Collapse
 
boira profile image
boira

Hi,

and how can I use that? I haven't found any parameter or way to add that in your example or in the repo.

Thank you very much for your help :-)

Thread Thread
 
abdeldjalilhachimi profile image
Abdeldjalil Hachimi

@boira
well first of all
install debounce ==> npm install debounce
and users like this in code
.....
import debounce from 'debounce';
const handlePlaceChanged = debounce(() => {
const place = autoComplete.getPlace();
if (!place.geometry || !place.geometry.location) {
/// do some stuff based on what you want
}
if (place.geometry.viewport || place.geometry.location) {
// do something
console.log(place.geometry.location);
}
}, 500); // Adjust the delay (in milliseconds) according to your needs

autoComplete.addListener('place_changed', handlePlaceChanged);

Thread Thread
 
boira profile image
boira

Hi,

I see, thanks :-).

I will try this approach and see. Nevertheless, I think that the problem is not appearing when getting the place details, but when users types things in the autocomplete input.

Eerytime that a user types a character in the input, many (20, 50...) requests to maps.googleapis.com/maps/api/place... are sent. After those requests, I can see the options to choose and when I click one of them the call to PlaceService.GetPlaceDetails (only one, this is good) is done.

I'll test this approach and investigate deeper. I am a backend developer so React is being a bit hard to understand. But I am very pleased with your help and ideas.

Keep in touch!

Collapse
 
lu_han profile image
Olaoluwa

Hello, thanks for this tutorial but I am having a major issue even though I wrote my code exactly as you taught. so after the process, the input field showed on the screen but when I try to search for a place I don't see an auto-complete plus on the map I am just getting a blank view. I also cloned your code from GitHub and I am getting the same issue. I used my google API key so my google API key might be the issue but I can see some errors and warnings in my console, I will paste them here maybe it will help give you a better context of my issue
"InvalidValueError: not an instance of HTMLInputElement"
"Google Maps already loaded outside @googlemaps/js-api-loader.This may result in undesirable behavior as options and script parameters may not match." - this is a warning in my console
"Source map error: No sources are declared in this source map.
Resource URL: localhost:5173/node_modules/.vite/...
Source Map URL: react.js.map" - another warning in my console
"Source map error: JSON.parse: unexpected character at line 1 column 1 of the JSON data
Resource URL: null
Source Map URL: react_devtools_backend_compact.js.map"

Image description
above is how the map field is showing and it does not display a map

Collapse
 
markothedev profile image
Nwokolo Ogechukwu Matthew

same here