Home > Software design >  getOptionLabel in material UI problems
getOptionLabel in material UI problems

Time:10-04

I have a constant like this :

const Reference = [
  { label: "RF-100", year: "Test" },
  { label: "RF-200", year: "Test2" },
  { label: "RF-300", year: "Test3" },
];

and I have my Autocomplete in MUI like this :

export const Auto: React.FC = () => {
  return (
    <Autocomplete
      id="Combox-demo"
      options={Reference}
      //getOptionLabel={(option) => `${option.name}`}
      style={{ width: 300 }}
      renderInput={(params) => <TextField {...params} label="Combo box" variant="outlined" prefix="RF" />}
    />
  );
};

I am trying to get my getOptionLabel to show label - year so It will be RF-100 - Test (as an example)

When I use

getOptionLabel={(option) => `${option.label}`}

I get

Property 'label' does not exist on type 'string | { label: string; year: string; }'. Property 'label' does not exist on type 'string'

Any ideas guys ?

CodePudding user response:

Problem

You are seeing in the TypeScript error that the option in your callback might either be an option object or just a string:

string | { label: string; year: string; }

The reason for this is due to the "free solo" mode of the Autocomplete, where the user can enter any arbitrary text and is not limited to just the provided options.

The docs for the getOptionLabel prop say:

If used in free solo mode, it must accept both the type of the options and a string.

Solution

You have two choices on how to proceed.

  1. You can check whether the option is a string. If if is not, then it must have the type { label: string; year: string; }. This involves a check at runtime but it is safer -- if you were to enable free solo mode then nothing would break, as you are properly handling string and object values.
getOptionLabel={(option) => typeof option === "string" ? option : option.label}
  1. If you are not using the freeSolo prop then you can make a type assertion. This is essentially telling TypeScript "trust me".
getOptionLabel={(option) => (option as { label: string }).label}
  • Related