helpful-purple
helpful-purple2mo ago

Controller autocomplete is not displaying defaultValue, but dropdown options are still correct

Hello! I have the following code, and I'm trying to fill the autocomplete box with the current value of the row from supabase. It doesn't seem to be doing that and I am not sure why.
<Controller
control={control}
name={"category_id"}
rules={{ required: "This field is required" }}
defaultValue={questionData?.category_id.category_name}
render={({ field }) => (
<Autocomplete
{...categoryAutocompleteProps}
{...field}
defaultValue={questionData?.category_id}
onChange={(_, value) => {
field.onChange(value.id);
}}
getOptionLabel={(item) => {
const found = categoryAutocompleteProps?.options?.find((p) => {
const itemId =
typeof item === "object"
? item?.id?.toString()
: item?.toString();
const pId = p?.id?.toString();
return itemId === pId;
})
return found?.category_name;
}}
isOptionEqualToValue={(option, value) => {
const optionId = option?.id?.toString();
const valueId =
typeof value === "object"
? value?.id?.toString()
: value?.toString();
return value === undefined || optionId === valueId;
}}
renderInput={(params) => (
<TextField
{...params}
label={"Category:"}
margin="normal"
variant="outlined"
error={!!(errors as any)?.category_id?.id}
helperText={(errors as any)?.category_id?.id?.message}
required
/>
)}
/>
)}
/>
<Controller
control={control}
name={"category_id"}
rules={{ required: "This field is required" }}
defaultValue={questionData?.category_id.category_name}
render={({ field }) => (
<Autocomplete
{...categoryAutocompleteProps}
{...field}
defaultValue={questionData?.category_id}
onChange={(_, value) => {
field.onChange(value.id);
}}
getOptionLabel={(item) => {
const found = categoryAutocompleteProps?.options?.find((p) => {
const itemId =
typeof item === "object"
? item?.id?.toString()
: item?.toString();
const pId = p?.id?.toString();
return itemId === pId;
})
return found?.category_name;
}}
isOptionEqualToValue={(option, value) => {
const optionId = option?.id?.toString();
const valueId =
typeof value === "object"
? value?.id?.toString()
: value?.toString();
return value === undefined || optionId === valueId;
}}
renderInput={(params) => (
<TextField
{...params}
label={"Category:"}
margin="normal"
variant="outlined"
error={!!(errors as any)?.category_id?.id}
helperText={(errors as any)?.category_id?.id?.message}
required
/>
)}
/>
)}
/>
9 Replies
kapa.ai
kapa.ai2mo ago
Hi @Strange. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Based on the provided code and the knowledge sources, I can offer some insights into why the autocomplete box is not displaying the default value as expected. Here are a few points to consider: 1. Default Value: The defaultValue prop you're using on the Controller component might not be the correct approach. Instead, you should use the defaultValue prop from the useForm hook when initializing your form. 2. Autocomplete Props: The useAutocomplete hook from refine provides autocomplete props that should be used with the Autocomplete component. Make sure you're using these props correctly. 3. Value Handling: The way you're handling the value in the onChange and getOptionLabel functions might need adjustment. Here's a suggested modification to your code based on the refine documentation:
const { autocompleteProps } = useAutocomplete({
resource: "categories",
defaultValue: questionData?.category_id,
});

// ...
<Controller
control={control}
name="category_id"
rules={{ required: "This field is required" }}
defaultValue={questionData?.category_id}
render={({ field }) => (
<Autocomplete
{...autocompleteProps}
{...field}
onChange={(_, value) => {
field.onChange(value);
}}
getOptionLabel={(item) => {
return (
autocompleteProps?.options?.find(
(p) => p?.id?.toString() === item?.id?.toString()
)?.category_name ?? ""
);
}}
isOptionEqualToValue={(option, value) =>
value === undefined ||
option?.id?.toString() === (value?.id ?? value)?.toString()
}
renderInput={(params) => (
<TextField
{...params}
label="Category"
margin="normal"
variant="outlined"
error={!!(errors as any)?.category_id}
helperText={(errors as any)?.category_id?.message}
required
/>
)}
/>
)}
/>
const { autocompleteProps } = useAutocomplete({
resource: "categories",
defaultValue: questionData?.category_id,
});

// ...
<Controller
control={control}
name="category_id"
rules={{ required: "This field is required" }}
defaultValue={questionData?.category_id}
render={({ field }) => (
<Autocomplete
{...autocompleteProps}
{...field}
onChange={(_, value) => {
field.onChange(value);
}}
getOptionLabel={(item) => {
return (
autocompleteProps?.options?.find(
(p) => p?.id?.toString() === item?.id?.toString()
)?.category_name ?? ""
);
}}
isOptionEqualToValue={(option, value) =>
value === undefined ||
option?.id?.toString() === (value?.id ?? value)?.toString()
}
renderInput={(params) => (
<TextField
{...params}
label="Category"
margin="normal"
variant="outlined"
error={!!(errors as any)?.category_id}
helperText={(errors as any)?.category_id?.message}
required
/>
)}
/>
)}
/>
This modification incorporates the following changes: 1. Use useAutocomplete hook to get the autocompleteProps. 2. Set the defaultValue in the useAutocomplete hook. 3. Simplify the onChange handler to pass the entire value object. 4. Adjust the getOptionLabel function to use the autocompleteProps.options. 5. Simplify the isOptionEqualToValue function. If you're still experiencing issues, you might want to check if the questionData?.category_id is in the correct format expected by the Autocomplete component. For more detailed information on using the Autocomplete component with refine, you can refer to the following resources: Material UI Autocomplete Component useAutocomplete Hook These resources provide additional examples and explanations that might help you troubleshoot your specific use case. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@812403974997147658> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
helpful-purple
helpful-purpleOP2mo ago
wow @kapa.ai
kapa.ai
kapa.ai2mo ago
Let me check the knowledge base for you again. One moment! :books: Sorry @Strange, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
helpful-purple
helpful-purpleOP2mo ago
oops @kapa.ai
kapa.ai
kapa.ai2mo ago
Let me check the knowledge base for you again. One moment! :books: Sorry @Strange, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
helpful-purple
helpful-purpleOP2mo ago
another:
<Controller
control={control}
name={"exam_studying_for"}
rules={{ required: "This field is required" }}
// eslint-disable-next-line
defaultValue={profileData?.exam_studying_for.id}
render={({ field }) => (
<Autocomplete
{...examAutocompleteProps}
{...field}
onChange={(_, value) => {
field.onChange(value.id);
}}
getOptionLabel={(item) => {
const found = examAutocompleteProps?.options?.find((p) => {
const itemId =
typeof item === "object"
? item?.id?.toString()
: item?.toString();
const pId = p?.id?.toString();
return itemId === pId;
})
return `${found?.exam_name} - ${found?.exam_description}`;
}}
isOptionEqualToValue={(option, value) => {
const optionId = option?.id?.toString();
const valueId =
typeof value === "object"
? value?.id?.toString()
: value?.toString();
return value === undefined || optionId === valueId;
}}
renderInput={(params) => (
<TextField
{...params}
label={"Exam Studying For:"}
margin="normal"
variant="outlined"
error={!!(errors as any)?.exam_studying_for?.id}
helperText={(errors as any)?.exam_studying_for?.id?.message}
required
/>
)}
/>
)}
/>
<Controller
control={control}
name={"exam_studying_for"}
rules={{ required: "This field is required" }}
// eslint-disable-next-line
defaultValue={profileData?.exam_studying_for.id}
render={({ field }) => (
<Autocomplete
{...examAutocompleteProps}
{...field}
onChange={(_, value) => {
field.onChange(value.id);
}}
getOptionLabel={(item) => {
const found = examAutocompleteProps?.options?.find((p) => {
const itemId =
typeof item === "object"
? item?.id?.toString()
: item?.toString();
const pId = p?.id?.toString();
return itemId === pId;
})
return `${found?.exam_name} - ${found?.exam_description}`;
}}
isOptionEqualToValue={(option, value) => {
const optionId = option?.id?.toString();
const valueId =
typeof value === "object"
? value?.id?.toString()
: value?.toString();
return value === undefined || optionId === valueId;
}}
renderInput={(params) => (
<TextField
{...params}
label={"Exam Studying For:"}
margin="normal"
variant="outlined"
error={!!(errors as any)?.exam_studying_for?.id}
helperText={(errors as any)?.exam_studying_for?.id?.message}
required
/>
)}
/>
)}
/>
Pressing the "Save" button on this edit page gives me an error:
Invalid input syntax for type bigint: "{"id":1,"exam_name":"SAT"}"
Error when updating profile (status code: 22)
Invalid input syntax for type bigint: "{"id":1,"exam_name":"SAT"}"
Error when updating profile (status code: 22)
@kapa.ai
kapa.ai
kapa.ai2mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Based on the code you've provided and the error message, it appears that there's an issue with the data type being sent to your database when saving the form. Let's analyze the problem and suggest a solution: 1. Error Analysis: The error message suggests that the database is expecting a bigint (a large integer) for the exam_studying_for field, but it's receiving a JSON object instead. 2. Problem in the Code: The issue is likely in the onChange handler of your Autocomplete component. You're setting the field value to value.id, but the field.onChange function is probably wrapping this in an object, resulting in the JSON string that's causing the error. 3. Suggested Solution: Modify your onChange handler to directly pass the ID as a number. Here's how you can adjust your code:
<Controller
control={control}
name="exam_studying_for"
rules={{ required: "This field is required" }}
defaultValue={profileData?.exam_studying_for?.id}
render={({ field }) => (
<Autocomplete
{...examAutocompleteProps}
{...field}
onChange={(_, value) => {
field.onChange(value ? value.id : null);
}}
getOptionLabel={(item) => {
const found = examAutocompleteProps?.options?.find(
(p) => p?.id?.toString() === (typeof item === 'object' ? item?.id?.toString() : item?.toString())
);
return found ? `${found.exam_name} - ${found.exam_description}` : '';
}}
isOptionEqualToValue={(option, value) =>
value === undefined ||
option?.id?.toString() === (value?.id ?? value)?.toString()
}
renderInput={(params) => (
<TextField
{...params}
label="Exam Studying For:"
margin="normal"
variant="outlined"
error={!!errors?.exam_studying_for}
helperText={errors?.exam_studying_for?.message}
required
/>
)}
/>
)}
/>
<Controller
control={control}
name="exam_studying_for"
rules={{ required: "This field is required" }}
defaultValue={profileData?.exam_studying_for?.id}
render={({ field }) => (
<Autocomplete
{...examAutocompleteProps}
{...field}
onChange={(_, value) => {
field.onChange(value ? value.id : null);
}}
getOptionLabel={(item) => {
const found = examAutocompleteProps?.options?.find(
(p) => p?.id?.toString() === (typeof item === 'object' ? item?.id?.toString() : item?.toString())
);
return found ? `${found.exam_name} - ${found.exam_description}` : '';
}}
isOptionEqualToValue={(option, value) =>
value === undefined ||
option?.id?.toString() === (value?.id ?? value)?.toString()
}
renderInput={(params) => (
<TextField
{...params}
label="Exam Studying For:"
margin="normal"
variant="outlined"
error={!!errors?.exam_studying_for}
helperText={errors?.exam_studying_for?.message}
required
/>
)}
/>
)}
/>
Key changes: 1. In the onChange handler, we're now passing just the id or null if no value is selected. 2. The defaultValue is set to profileData?.exam_studying_for?.id to ensure we're passing just the ID. 3. The error handling in the TextField has been simplified to directly access errors.exam_studying_for. These changes should resolve the type mismatch error you're encountering. The database will now receive a bigint value as expected, rather than a JSON object. For more information on handling form submissions and data types with refine and Material-UI, you can refer to the refine documentation on forms. If you continue to experience issues, you may need to check your backend API or database schema to ensure they're correctly set up to handle the exam_studying_for field as a bigint. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@812403974997147658> Kapa.ai is still learning and improving, please let me know how I did by reacting below.

Did you find this page helpful?