Comments (13)
If you want to dynamically load in the Google script when component mounts, this worked for me:
// hook
const { init /*, ...rest */ } = usePlacesAutocomplete({
initOnMount: false,
});
// component
<Script
src="https://maps.googleapis.com/maps/api/js?key=${GOOGLE_PLACES_KEY}&libraries=places"
onReady={init}
/>
from use-places-autocomplete.
Per the recent Nextjs shift in best practices for loading beforeInteractive scripts, you can instantiate the library as pictured and it works perfectly. I’m using next@latest, edge middleware, etc etc; works with [email protected]
if anyone has tips for using the returned latlng values with Algolia InstantSearch Hooks it’d be much appreciated. I currently have it all working in isolation; but when using both Google places and algolia in the same form the fetching strategies clash I think (fiddling with Promise.all([]) but might say fuck it and use global context, keep the worlds separate).
That said, it would be dope to see an algolia-instantsearch-hooks use places autocomplete integration
Did you have working like this?
from use-places-autocomplete.
Per the recent Nextjs shift in best practices for loading beforeInteractive scripts, you can instantiate the library as pictured and it works perfectly. I’m using next@latest, edge middleware, etc etc; works with [email protected]
if anyone has tips for using the returned latlng values with Algolia InstantSearch Hooks it’d be much appreciated. I currently have it all working in isolation; but when using both Google places and algolia in the same form the fetching strategies clash I think (fiddling with Promise.all([]) but might say fuck it and use global context, keep the worlds separate).
That said, it would be dope to see an algolia-instantsearch-hooks use places autocomplete integration
from use-places-autocomplete.
Reason:
This issue occurs when usePlacesAutocomplete
is initialized before the Google Maps script is loaded.
Solution:
This can be accomplished with any of the strategies.
beforeInteractive
should anyways work as the google map script is loaded initially. But if it doesn't, same solution can be applied for that as well.- if we have issues with
afterInteractive
orlazyOnLoad
. we can do the following:
A. We set a flag somewhere in redux/zustand/context when the google maps script is loaded. The placement of script tag will depend on the use cases like:
- If we are using external stores like
zustand
we can placed the script in_document.tsx
- In case of
context
, the script needs to be places within the boundaries of context to be able to set the flag there.
<Script
id="googlemaps"
type="text/javascript"
strategy="lazyOnLoad"
src="https://maps.googleapis.com/maps/api/js?key=KEY-4Q&libraries=places"
onLoad={() => useMapStore.setState({ isMapScriptLoaded: true })}
/>
B. Wherever we are using usePlacesAutoComplete
, we delay initialization of the hook based on our flag:
const isMapScriptLoaded = useMapStore((state) => state.isMapScriptLoaded);
const { init } = usePlacesAutocomplete({ initOnMount: false });
useEffect(() => {
if (isMapScriptLoaded) {
init();
}
}, [isMapScriptLoaded]);
The above example uses a zustand store, same can be implemented for redux or context as well.
from use-places-autocomplete.
Hey there: @paularah
What I have on my NextJS app v. 12.2.5 and seems to be working is putting the <Script /> from NextJs like this on the _document.js
page.
However, this doesn't work for me when I put it on a single page inside the pages
folder. So I guess the downside to it is that it will load mostly on every page, perhaps hurting performance, but I'm not 100% sure, so I don't want to claim things like that.
In short, putting it on _document.js
should work!
from use-places-autocomplete.
@avaneeshtripathi thanks a lot! Your solution with init() worked well. Had issue waiting for loads on refresh and this solves it!
from use-places-autocomplete.
I have this problem too
from use-places-autocomplete.
@DopamineDriven Thanks.
Is that code in "pages/_document.js"? I have similar code in document and it's not working for me.
import { Html, Head, Main, NextScript } from "next/document";
import Script from "next/script";
export default function Document() {
return (
<Html>
<Head />
<body>
<Main />
<NextScript />
<Script
id="googlemaps"
type="text/javascript"
strategy="beforeInteractive"
src="https://maps.googleapis.com/maps/api/js?key=KEY-4Q&libraries=places"
/>
</body>
</Html>
);
}
from use-places-autocomplete.
Without making the script available everywhere, putting it in _document
, only this helped resolve the issue: #883 (comment)
Edit: the above only partially worked, since it would load once and no longer work on refresh.
Workaround: vercel/next.js#17919 (comment)
from use-places-autocomplete.
I had same problem.
After some digging, I was able to work around using "use-google-maps-script" package hook.
Using this package, I was able to wait until script is loaded and then call the component to usePlacesAutocomplete.
from use-places-autocomplete.
@nyfever007 any chance you can paste a snippet? I tried reproducing your approach with no success.
from use-places-autocomplete.
@paularah By using use-google-maps-script package you can wait until script is loaded then call your address component.
import { Libraries, useGoogleMapsScript } from 'use-google-maps-script';
const libraries: Libraries = ['places'];
const App = () => {
const { isLoaded, loadError } = useGoogleMapsScript({
googleMapsApiKey: process.env.NEXT_PUBLIC_GOOLGE_MAPS_API_KEY!,
libraries,
});
return(
<div>
{isLoaded && (
<AutoPlacesAddress setSelectedAddress={setSelectedAddress} defaultValue={null} />
)}
</div>
)
}
export default App
import { useRef } from 'react';
import usePlacesAutocomplete, { getDetails, getGeocode, getLatLng,} from 'use-places-autocomplete';
import { useOnClickOutside } from 'usehooks-ts';
type Props = { setSelectedAddress: React.Dispatch<React.SetStateAction<AddressFormValues>>;
defaultValue: string | null;};
const AutoPlacesAddress = ({ setSelectedAddress, defaultValue }: Props) => {
const {
ready,
value,
suggestions: { status, data },
setValue,
clearSuggestions,
} = usePlacesAutocomplete({
requestOptions: {
/* Define search scope here */
},
debounce: 500,
});
const handleInput = (e: React.ChangeEvent<HTMLInputElement>): void => {
setValue(e.target.value);
};
const ref = useRef(null);
const handleClickOutside = () => {
// use useOnClickOutside hook to close the suggestions when user clicks outside of the component
clearSuggestions();
};
useOnClickOutside(ref, handleClickOutside);
const handleSelect =
(suggestion: { description: string; place_id: string }) => async () => {
// When user selects a place, we can replace the keyword without request data from API
// by setting the second parameter to "false"
setValue(suggestion.description, false);
const placeId = {
placeId: suggestion.place_id,
};
clearSuggestions();
try {
const latlng = await getGeocode({ address: suggestion.description });
const { lat, lng } = getLatLng(latlng[0]);
const detail: any = await getDetails(placeId);
setSelectedAddress({
address: suggestion.description,
lat: lat,
lng: lng,
});
} catch (error) {
console.log(error);
}
};
const renderSuggestions = () =>
data.map((suggestion) => {
const {
place_id,
structured_formatting: { main_text, secondary_text },
} = suggestion;
return (
<li
key={place_id}
onClick={handleSelect(suggestion)}
className='w-full cursor-pointer border-b py-1 px-4 last-of-type:border-0 hover:bg-indigo-500 hover:text-white'
>
<div>
{main_text} <small>{secondary_text}</small>
</div>
</li>
);
});
return (
<>
<div ref={ref} className='relative'>
<input
value={value}
onChange={handleInput}
disabled={!ready}
placeholder={defaultValue!}
className='form-input w-full rounded-md border-neutral-300 outline-none focus:border-dark-900 focus:outline-0 focus:ring-0'
/>
{/* We can use the "status" to decide whether we should display the dropdown or not */}
{status === 'OK' && (
<ul className='absolute top-10 w-full rounded-md border bg-neutral-50'>
{renderSuggestions()}
</ul>
)}
</div>
</>
);
};
export default AutoPlacesAddress;
from use-places-autocomplete.
Adding defer solve this issue for me
<Script defer id="googlemaps" src="https://maps.googleapis.com/maps/api/js?key=''&libraries=places" strategy="beforeInteractive" type="text/javascript" />from use-places-autocomplete.
Related Issues (20)
- @types/googlemaps is deprecated in favor of @types/google.maps HOT 1
- show suggestions by default
- You have included the Google Maps JavaScript API multiple times on this page HOT 1
- How to use service.nearbySearch( )
- `getAddressComponent` utility function HOT 3
- Feature request: Cache support for utility functions
- TypeError: Cannot read properties of undefined (reading 'maps') at getGeocode
- use getGeocode before usePlacesAutocomplete
- request a new working example HOT 1
- [Feature] Display all the info returned from the serch in the page
- Google API now requires callback function parameter HOT 16
- Limit the search to a specific area HOT 3
- Is administrativeArea accepted in componentRestrictions
- Bounds, location, and radius in the Maps JavaScript API Place Autocomplete Service (Deprecated as of May 2023) HOT 3
- Granular address_components not available in data response?
- Live demo doesn't work HOT 1
- Do all hooks share the same context?
- Configurable Retry with Exponential Backoff HOT 2
- Does getLatLng util really need to be async? HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from use-places-autocomplete.