I wish to create a autocomplete search bar with my own custom call to the backend, which searches through a list of tickers.
<Autocomplete
multiple
id="checkboxes-tags-demo"
options={watchlistSearchTickers}
disableCloseOnSelect
getOptionLabel={(option: any) => (option!) ? option.Symbol : null}
renderOption={(props, option, { selected }) => (
<li {...props}>
{option.Symbol}
</li>
)}
style={{ padding: 0 }}
onChange={(event, query: any) => handleWatchlistSearch(query)}
filterOptions={(x) => x}
renderInput={(params) => (
<div ref={params.InputProps.ref}>
<input type="text" {...params.inputProps} />
</div>
)}
/>
The initial render here seems fine, but on click the text input box, an error "options.filter" is not a function
occurs. Here is the function that calls the backend through a post request:
const [watchlistSearchTickers, setWatchlistSearchTickers] = useState<Array<watchlistSearchInterface>>([])
function handleWatchlistSearch(query: string) {
axiosInstance.post("/portfolio/watchlist/search/", {
query: query
}).then((res) => {
console.log(res)
setWatchlistSearchTickers(res.data)
})
}
useEffect(() => {
handleWatchlistSearch("")
}, []) // Initialize with empty list of tickers
Does anyone know why this happens?
So this bug actually happens when you pass null
or undefined
values into the options
prop of the Autocomplete component. This is likely happening because you're clicking in the Autocomplete "too fast", so before it can get the results from your API call, it passes a value that the component tries to .filter()
it, causing the error.
I was also having this issue, and I managed to figure a workaround that works (it's not perfect but it stops your code from crashing).
<Autocomplete
multiple
id="checkboxes-tags-demo"
options={!watchlistSearchTickers ? [{label:"Loading...", id:0}] : watchlistSearchTickers }
(...)
With this ternary, what we do is that while your API is working on your request, it puts a placeholder "Loading..." option so it won't crash your code (Similar-ish to the Load on open prop, but I never figured how to make that work).
For me the solution above works well, but the fanciest and best choice would be the Load prop that is something from MUI.
Hope I could help!
Edit: Actually, if you can initialize your options to an empty array [], you can set the loading prop as true, which will display loading while your content loads!