Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Autocomplete warning: You can use the `isOptionEqualToValue` prop to customize the equality test

I am trying to eliminate this warning

MUI: The value provided to Autocomplete is invalid.
None of the options match with `""`.
You can use the `isOptionEqualToValue` prop to customize the equality test. 

I go through a lot of Stack Overflow, it doesn't work. What am I missing here

const DropDownSearch = ({
  setSelectedValue,
  width = "auto",
  label = "",
  options = [],
  defaultSelectedValue = "",
}) => {
  console.log("🚀 DropDownInitiated ==", label);

  const selectedVendorCode = setSelectedValue;
  const [value, setValue] = useState(""); //selected value
  const [inputValue, setInputValue] = useState(""); //user typing value/ display text
  const [defaultValueIndex, setDefaultValueIndex] = useState(-1);

  useEffect(() => {
    // TODO: find default value index,
    // TODO: to make selection as defualtValue
    if (defaultSelectedValue.length > 0) {
      
      const findIndex = options.findIndex(
        (opt) => opt.value === defaultSelectedValue
      );
      console.log("findIndex =>>> ", findIndex);
      setDefaultValueIndex(findIndex);
    }
  }, [defaultSelectedValue]);

  useEffect(() => {
    // TODO: once "useState value" (user selected value) changed,
    // TODO: then send to parent component
    if(value){
      setSelectedValue?.(value);
    }
  }, [value]);

  const optionData = useMemo(() => {
    return options;
  }, [options]);


  const filterOptions = createFilterOptions({
    stringify: (option) => {
      return JSON.stringify(Object.values(option));
    },
  });

  return (
    <Autocomplete
      defaultValue={
        (defaultValueIndex >= 0) ? optionData[defaultValueIndex] : null
      }
      key={optionData.value}

      isOptionEqualToValue={(option, value) => (value === undefined)? false : (option.value === '""')? false : option.value === value.value}
      //   {
      //   value ? option.value === value.value : false;
      //   if(!value) return false;
      //   if(value.value ==='""') return false;
      //   // console.log('option.value ==> ',option.value)
      //   // console.log(option)
      //    console.log('value.value ==> ',value.value)
      //   // console.log(value)
      //   return option.value === value.value;
      // }}
      
      filterOptions={filterOptions}
      componentsProps={{ popper: { style: { width: "fit-content" } } }}
      size="small"
      id="dropdown-search"
      value={value}
      onChange={(event, newValue) => {
        // TODO: set user selected value as OBJECT
        setValue(newValue);
      }}
      inputValue={inputValue}
      onInputChange={(event, newInputValue) => {
        // TODO: this value is when user type on each key press
        setInputValue(newInputValue);
      }}
      width={width}
      options={optionData}
      autoHighlight
      /**
       *  ! renderOption
       *  this will show list of options, as a table format in dropdown list
       */
      renderOption={(props, option, index) => (
        <Box
          component="li"
          {...props} 
          style={{ display: "table-row" }}
          sx={{ "& > img": { mr: 2, flexShrink: 0 } }}
         
          key={JSON.stringify(Object.values(option))}
        >
          {Object.keys(option).map((key, index) => (
            <div style={{ display: "table-cell", padding: "5px" }} key={index}>
              {option[key]}
            </div>
          ))}
        </Box>
      )}
      renderInput={(params) => (
        <TextField
          {...params}
          label={label}
          inputProps={{ ...params.inputProps, autoComplete: "new-password" }}
        />
      )}
    />
  );
};

my dropdown list will host objects example:

options = [
    {label:'xxx1',value:'yyy1'},
    {label:'xxx2',value:'yyy2'}
]

I confirmed that there is no options.label or options.value = ""

I tried many things like below

this way

isOptionEqualToValue={(option, value) => option.value === value.value

also this

isOptionEqualToValue={(option, value) => {

         if(!value) return false;
         if(option.value ==="") return false;
         if(option.value ==='""') return false;
         if(value.value ==="") return false;
         if(value.value ==='""') return false;

         return option.value === value.value;
}}
like image 966
Liam neesan Avatar asked Oct 27 '25 06:10

Liam neesan


1 Answers

You would not need some extra-complexity with isOptionEqualToValue. There is no need to define this property (neither the defaultValue one), and just set the non-selected value to null instead of an empty string ("").

Here is an example of a controlled Autocomplete implementation:

const options = [
  { label: "The Shawshank Redemption", value: 1 },
  { label: "The Godfather", value: 2 }
];

export default function AutocompleteComponent() {
  // Value is null by default
  const [value, setValue] = useState(null);

  // Input value is an empty string by default
  const [inputValue, setInputValue] = useState("");

  return (
    <Autocomplete
      options={options}
      value={value}
      onChange={(event, newValue) => {
        setValue(newValue);
      }}
      inputValue={inputValue}
      onInputChange={(event, newInputValue) => {
        setInputValue(newInputValue);
      }}
      renderInput={(params) => <TextField {...params} label="Movie" />}
    />
  );
}

You can find a simplified working example on CodeSandbox.

like image 123
Michaël Perrin Avatar answered Oct 28 '25 19:10

Michaël Perrin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!