Search code examples
javascriptreactjsgoogle-maps

@react-google-maps/api Autocomplete component returning undefined onPlaceChanged


I am having difficulty using the Autocomplete component in @react-google-maps/api. Autocomplete itself works and will display options. Clicking an option populates the input box but I only return 'undefined' from the Places Api. I have avoided using something like PlacesAutocomplete because I prefer the built in result rendering from Google.

Edited: App.js file should be minimally functional with use of an appropriate API key.

import React, { useState, useRef} from 'react';
import { Autocomplete, useLoadScript } from '@react-google-maps/api';

const placesLibrary = ['places']


function App() {
  const [searchResult, setSearchResult] = useState('')

  const autocompleteRef = useRef();

  const { isLoaded } =  useLoadScript({
    googleMapsApiKey: 'GOOGLE_API_KEY',
    libraries: placesLibrary
});

  const onLoad = () => {
     const autocomplete = autocompleteRef.current
  }

  const onPlaceChanged = (place) => {
    setSearchResult(place)
    console.log(searchResult)
  }

  if(!isLoaded) {
    return <div>Loading...</div>
    };


  return (
    <div className="App">
    
    
        <div id="searchColumn">
            <h2>Tide Forecast Options</h2>
            <Autocomplete
            onPlaceChanged={(place) => onPlaceChanged(place)}
            onLoad = {onLoad}>

                <input
                type="text"
                placeholder="Search for Tide Information"
                style={{
                    boxSizing: `border-box`,
                    border: `1px solid transparent`,
                    width: `240px`,
                    height: `32px`,
                    padding: `0 12px`,
                    borderRadius: `3px`,
                    boxShadow: `0 2px 6px rgba(0, 0, 0, 0.3)`,
                    fontSize: `14px`,
                    outline: `none`,
                    textOverflow: `ellipses`,
                }}
                />
            </Autocomplete>
        </div>
    </div>    
  )}

export default App;

Solution

  • I was able to reproduce your code and found some unnecessary stuff you have included like the useRef, autocompleteRef but you could just clarify things in the comment. And also I did not find the way you used the onPlaceChanged and onLoad events on the @react-google-maps/api Library Docs. So I just based what I did there and removed some stuff you put.

    Here's what the code looks like:

    first is that onLoad() function for the <Autocomplete /> already had a built in parameter called autocomplete that returns the result of the autocomplete by using getPlace(). ref here. So what I did here is I changed the value of searchResult state with what the result of the autocomplete returns using setSearchResult(autocomplete) inside the onload() function.

      function onLoad(autocomplete) {
        setSearchResult(autocomplete);
      }
    

    Then on the onPlaceChanged() function, I used the new searchResult value to get the place details.

      function onPlaceChanged() {
        if (searchResult != null) {
          //variable to store the result
          const place = searchResult.getPlace();
          //variable to store the name from place details result 
          const name = place.name;
          //variable to store the status from place details result
          const status = place.business_status;
          //variable to store the formatted address from place details result
          const formattedAddress = place.formatted_address;
          // console.log(place);
          //console log all results
          console.log(`Name: ${name}`);
          console.log(`Business Status: ${status}`);
          console.log(`Formatted Address: ${formattedAddress}`);
        } else {
          alert("Please enter text");
        }
      }
    

    You can remove the comment from console.log(place) if you want to check what's inside the variable place result and use that as a reference if you want to get other details from the autocomplete result.

    Then I just changed your callbacks inside your onLoad and onPlaceChanged props to simply call on to the functions above.

      return (
        <div className="App">
          <div id="searchColumn">
            <h2>Tide Forecast Options</h2>
            <Autocomplete onPlaceChanged={onPlaceChanged} onLoad={onLoad}>
              <input
                type="text"
                placeholder="Search for Tide Information"
                style={{
                  boxSizing: `border-box`,
                  border: `1px solid transparent`,
                  width: `240px`,
                  height: `32px`,
                  padding: `0 12px`,
                  borderRadius: `3px`,
                  boxShadow: `0 2px 6px rgba(0, 0, 0, 0.3)`,
                  fontSize: `14px`,
                  outline: `none`,
                  textOverflow: `ellipses`
                }}
              />
            </Autocomplete>
          </div>
        </div>
      );
    

    With this, things seems to be working fine.

    Here's a code sandbox if you want to try this out (Just use your own API key): https://codesandbox.io/s/react-google-maps-api-multiple-markers-infowindow-forked-dpueyy?file=/src/App.js

    Hope this helps.