Reputation: 487
I don't know what I am doing wrong but I cannot access the option.slug
from the object I receive from the API. I am trying to change pass a URL slug and change the route of my app. I am trying to do this using the onChange
prop inside my useAutocomplete()
definition.
Accessing the option.slug
or any other property works well inside of my JSX structure. As you can see I am grabbing option.title
and so on to render my list items which works well...
Instead of grabbing the actual slug I keep getting the route of "/components/undefined"
But when I try accessing the option.slug
on the top level of my component in the useAutocomplete()
definition it doesn't seem to work. Based on the original documentation though, that's the way to do it.
https://material-ui.com/components/autocomplete/#useautocomplete
export default function NavigationSearch({ onClose, results }) {
const router = useRouter();
const {
getRootProps,
getInputLabelProps,
getInputProps,
getListboxProps,
getOptionProps,
groupedOptions
} = useAutocomplete({
id: 'use-autocomplete-demo',
options: results,
getOptionLabel: (option) => option.title,
onChange: (option) => router.push(`/components/${option.slug}`)
});
return (
<React.Fragment>
{/* 1. SEARCH INPUT */}
<Container maxWidth="md" disableGutters>
<Box display="flex" width="100%">
<motion.div
style={{ width: 'inherit' }}
initial="hidden"
animate="visible"
variants={animation}>
<Box display="flex" width="inherit">
<Search width="inherit" {...getRootProps()}>
<SearchIcon color="primary" />
<InputBase
placeholder="Search for components, patterns..."
style={{ color: 'inherit', width: 'inherit' }}
autoFocus
{...getInputProps()}
/>
</Search>
</Box>
</motion.div>
<IconButton color="primary" onClick={onClose}>
<CloseIcon />
</IconButton>
</Box>
</Container>
{/* SEARCH RESULTS */}
<BackdropOverlay open={true} onClick={onClose}>
<Container maxWidth="md" disableGutters>
{groupedOptions.length > 0 ? (
<Results>
<List
{...getListboxProps()}
subheader={
<Box paddingX={2}>
<Typography
variant="overline"
color="textSecondary"
gutterBottom>
Popular search results
</Typography>
</Box>
}>
{groupedOptions.map((option, index) => (
<Item
button
key={option.title}
{...getOptionProps({
option,
index
})}>
<Box
display="flex"
justifyContent="space-between"
width="100%">
<Box>
<Typography color="textPrimary">
{option.title}
</Typography>
<Typography variant="caption" color="textSecondary">
{option.type}
</Typography>
</Box>
<Box alignSelf="flex-end">
<Typography variant="caption" color="textSecondary">
/components/button
</Typography>
</Box>
</Box>
</Item>
))}
</List>
</Results>
) : null}
</Container>
</BackdropOverlay>
</React.Fragment>
);
}
This is the API response that I store in the results prop:
0: {id: 1, title: "Button", slug: "button"}
1: {id: 2, title: "Switch", slug: "switch"}
2: {id: 3, title: "Tags", slug: "tags"}
3: {id: 4, title: "Checkbox", slug: "checkbox"}
4: {id: 5, title: "Toast", slug: "toast"}
Upvotes: 2
Views: 363
Reputation: 81585
Autocomplete
component uses useAutocomplete
hook under the hood so they share the same API. In Autocomplete
API. This is the signature of onChange
:
function(event: object, value: T | T[], reason: string) => void
The second argument is the option value which is what you need here. So change your code to:
onChange: (_, option) => router.push(`/components/${option.slug}`)
To fix the undefined
value issue.
Upvotes: 2