I need to implement the Google Places Search Box using the Google Place Autocomplete feature as it is shown here. And it should be allow the user to select a location from the search box.
The sample code is in JavaScript and what I need is to implement it in my react application.
import React, { useEffect, useRef, useState } from 'react';
import { LoadScript } from '@react-google-maps/api';
export default function GoogleMapSearchBox() {
const mapRef = useRef(null);
const [map, setMap] = useState(null);
const [searchBox, setSearchBox] = useState(null);
const handlePlacesChanged = () => {
const places = searchBox.getPlaces();
if (places.length == 0) {
return;
}
const bounds = new google.maps.LatLngBounds();
places.forEach((place) => {
if (!place.geometry || !place.geometry.location) {
console.log('Returned place contains no geometry');
return;
}
const markers = mapRef.current.getMarkers();
markers.forEach((marker) => {
marker.setMap(null);
});
const marker = new google.maps.Marker({
map,
title: place.name,
position: place.geometry.location,
});
mapRef.current.addMarker(marker);
if (place.geometry.viewport) {
bounds.union(place.geometry.viewport);
} else {
bounds.extend(place.geometry.location);
}
});
map.fitBounds(bounds);
};
useEffect(() => {
if (!mapRef.current) return;
const mapInstance = new google.maps.Map(mapRef.current, {
center: { lat: -33.8688, lng: 151.2195 },
zoom: 13,
mapTypeId: 'roadmap',
});
setMap(mapInstance);
const input = document.getElementById('pac-input');
const searchBoxInstance = new google.maps.places.SearchBox(input);
mapInstance.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
mapInstance.addListener('bounds_changed', () => {
searchBoxInstance.setBounds(mapInstance.getBounds());
});
setSearchBox(searchBoxInstance);
}, []);
return (
<div style={{ height: '300px', width: '100%' }}>
<LoadScript
googleMapsApiKey={process.env.GOOGLE_API_KEY}
libraries={['places']}
>
<div id="map" ref={mapRef} />
</LoadScript>
<input
className="mt-5"
type="text"
id="pac-input"
placeholder="Search for a place"
/>
</div>
);
}
So far I have done this and need to know what I am doing wrong.
"use client";
import React, { useState } from "react";
import {
useLoadScript,
GoogleMap,
Marker as AdvancedMarkerElement,
} from "@react-google-maps/api";
const libraries = ["places"];
const GoogleMapComp = ({ className }) => {
const [map, setMap] = useState(null);
const [location, setLocation] = useState({
lat: 6.925187004369271,
lng: 79.86128293151192,
});
const { isLoaded, loadError } = useLoadScript({
googleMapsApiKey: process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY,
libraries,
loading: "async",
});
const handleMapLoad = (mapInstance) => {
setMap(mapInstance);
};
const handleClick = (event) => {
setLocation({
lat: event.latLng.lat(),
lng: event.latLng.lng(),
});
};
if (loadError) return "Error loading maps";
if (!isLoaded) return "Loading maps";
return (
<div className={className}>
<GoogleMap
mapContainerStyle={{ width: "100%", height: "100%" }}
zoom={13}
center={{ lat: 6.925187004369271, lng: 79.86128293151192 }}
onLoad={handleMapLoad}
onClick={handleClick}
>
{location && <AdvancedMarkerElement position={location} />}
</GoogleMap>
</div>
);
};
export default GoogleMapComp;