I found an issue with compareOption function when changes getOptionValue and getOptionLabel to a different (value|label) structure.= using with AsyncCreatable.
Follow the example to replicate.
The options are loaded from an endpoint using callback handler, with the JSON structure: [{ id: 1, name: 'teste1' }, { id: 2, name: 'teste2' }, { id: 3, name: 'teste3' } ]
const customFilter = createFilter({
ignoreCase: false,
ignoreAccents: false,
trim: false,
matchFrom: 'any',
});
<AsyncCreatableSelect
name="tag"
id="tag"
isMulti
isClearable
placeholder="Marque algumas tags para este registro"
getOptionValue={option => option.id}
getOptionLabel={option => option.id}
filterOption={customFilter}
loadingMessage={e => `Carregando op莽玫es pr贸ximas de '${e.inputValue}'`}
noOptionsMessage={e => `Sem op莽玫es dispon铆veis para escolha`}
formatCreateLabel={e => `Criar uma nova tag com r贸tulo '${e}'`}
components={{ Option: Option, ...makeAnimated() }}
loadOptions={loadOptions}
/>
Uncaught TypeError: Cannot read property 'toLowerCase' of undefined
at compareOption (Creatable.js?067d:40)
at eval (Creatable.js?067d:51)
at Array.some (
at isValidNewOption (Creatable.js?067d:50)
at Creatable.componentWillReceiveProps (Creatable.js?067d:133)
at callComponentWillReceiveProps (react-dom.development.js?cada:11528)
at updateClassInstance (react-dom.development.js?cada:11720)
at updateClassComponent (react-dom.development.js?cada:13154)
at beginWork (react-dom.development.js?cada:13825)
at performUnitOfWork (react-dom.development.js?cada:15864)
When I got the function:
var compareOption = function compareOption(inputValue, option) {
var candidate = inputValue.toLowerCase();
return option.value.toLowerCase() === candidate || option.label.toLowerCase() === candidate;
};
The workaround was creating a function to put the structure in the same value|label model that the compoment was made for.
const organizeOptions = array => {
var items = [];
for (var index in array) {
items.push({ value: array[index].name, label: array[index].name });
}
return items;
};
trying to do a PR for that
I think, it has already multiple PR about that subject ...
I also did it by overriding :
getNewOptionData={(inputValue, optionLabel) => {
return {
id: inputValue,
value: optionLabel,
__isNew__: true};
}}
isValidNewOption={(inputValue, selectValue, selectOptions) => {
const compareOption = (inputValue, option) => {
const getOptionValue = (option) => option.id;
const getOptionLabel = (option) => option.value;
const candidate = inputValue.toLowerCase();
return (
getOptionValue(option).toLowerCase() === candidate ||
getOptionLabel(option).toLowerCase() === candidate
);
}
return !(!inputValue ||
selectValue.some(option => compareOption(inputValue, option)) ||
selectOptions.some(option => compareOption(inputValue, option)));
}}
onCreateOption={inputValue => this.createNewElementFromSelect(inputValue)}
Same issue here. Cannot use Creatable because it doesnt respect getOptionValue and getOptionLabel props.
Uncaught TypeError: Cannot read property 'toLowerCase' of undefined
at compareOption (Creatable.js?067d:40)
Echoing @nehaleem and @vrbarros
Creatable ignores custom getOptionValue and getOptionLabel. My solution was to transform options array before hand
Seems like this is a duplicate of https://github.com/JedWatson/react-select/issues/2953, right?
I had this issue.
I found an issue with compareOption function when changes getOptionValue and getOptionLabel to a different (value|label)
Reason why it is throwing this error: compareOption function is trying to first toLowerCase() the option value and label and then compare it with the characters (string) we are typing. So if you are passing anyone of them (value and label) as number or other than string, it will throw an error.
1. Mapped the array before hand:
let states = statesArray.map(m => {
return {
value: m.id.toString(),
label: m.stateName
}
});
Creatable Component<Creatable
className="basic-single"
classNamePrefix="select"
name="states"
options={states}
isMulti
/>
I did the same as @vrbarros but added a fallback to ""
@const organizeOptions = array => {
var items = [];
for (var index in array) {
items.push({ value: array[index].name || "", label: array[index].name || "" });
}
return items;
};
Hello -
In an effort to sustain the react-select project going forward, we're closing old issues.
We understand this might be inconvenient but in the best interest of supporting the broader community we have to direct our efforts towards the current major version.
If you aren't using the latest version of react-select please consider upgrading to see if it resolves any issues you're having.
However, if you feel this issue is still relevant and you'd like us to review it - please leave a comment and we'll do our best to get back to you!
For completeness, the props formatCreateLabel, isValidNewOption and getNewOptionData props were introduced to Creatable to fix this and other related issues - docs here
If anybody comes across this issue and is experiencing something similar to the problems described here, please open a new issue with details so we can track down anything we missed.
Thanks!
Most helpful comment
Same issue here. Cannot use
Creatablebecause it doesnt respectgetOptionValueandgetOptionLabelprops.