Reputation: 1
I am having the issue when I try and use the Places API for address autocomplete in React with ts. When I run the project again the address autocomplete does fill out the address forms correctly but when I actually stay on that page and pick new address after new address and then refresh I start getting TypeErrors like the one mentioned in the title as well as this error You have included the Google Maps JavaScript API multiple times on this page. This may cause unexpected errors.
Following code resulting in the error:
declare global {
interface Window {
initMap: () => void;
}
}
window.initMap = window.initMap || (() => setGoogleMapsLoaded(true));
const loader = new Loader({
apiKey: import.meta.env.VITE_GOOGLE_MAP_IMBED_API_KEY,
version: "weekly",
libraries: ["places"],
});
useEffect(() => {
loader.load().then(() => {
setGoogleMapsLoaded(true);
});
}, []);
const autocompleteInputRef = useRef(null);
useEffect(() => {
(async () => {
if (!isGoogleMapsLoaded || !autocompleteInputRef.current) return;
try {
if (
!window.google ||
!window.google.maps ||
!window.google.maps.places
) {
return "bad";
}
if (!autocompleteInputRef.current) return;
const autocomplete = new window.google.maps.places.Autocomplete(
autocompleteInputRef.current,
{
types: ["address"],
componentRestrictions: { country: "us" },
}
);
console.log(autocomplete);
autocomplete.addListener("place_changed", () => {
const place = autocomplete.getPlace();
if (!place || !place.address_components) return;
const streetAddress1Component = place.address_components.find(
(component) => component.types.includes("street_number")
);
const streetAddress2Component = place.address_components.find(
(component) => component.types.includes("route")
);
const cityComponent = place.address_components.find((component) =>
component.types.includes("locality")
);
const stateComponent = place.address_components.find((component) =>
component.types.includes("administrative_area_level_1")
);
const zipCodeComponent = place.address_components.find((component) =>
component.types.includes("postal_code")
);
if (
!streetAddress1Component ||
!streetAddress2Component ||
!cityComponent ||
!stateComponent ||
!zipCodeComponent
) {
// Fallback mechanism to parse the full address
const fullAddress = place.formatted_address
? place.formatted_address.split(", ")
: [];
setFormData({
...formData,
streetAddress1: fullAddress[0] || "",
city: fullAddress[1] || "",
state: fullAddress[2]?.split(" ")[0] || "",
zipCode: fullAddress[2]?.split(" ")[1] || "",
});
} else {
const streetAddress1 = streetAddress1Component.long_name;
const streetAddress2 = streetAddress2Component.long_name;
const city = cityComponent.long_name;
const state = stateComponent.short_name;
const zipCode = zipCodeComponent.long_name;
setFormData({
...formData,
streetAddress1: `${streetAddress1} ${streetAddress2}`,
city,
state,
zipCode,
});
}
});
} catch (error) {
console.error(error);
}
})();
}, [isGoogleMapsLoaded, autocompleteInputRef.current]);
Like I said with the current code I have there it does work properly sometimes but other times it starts giving me the TypeError and then just stops working completely.
Upvotes: 0
Views: 192
Reputation: 1
I ended up going with a different library completely when finding a solution to this. As you can see in the updated code I used Loader which worked better in my use case.
Upvotes: -2