question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Async multi-select removing values on search

See original GitHub issue

Hi everyone,

I’m having a weird issue when searching on an async multi-select. When I visit my page, I have five users already loaded in the value (Tammy, Sherri, Tonia, Jessica, Jamie). When I start to search on that input to add more users, some of these values disappear depending on what I’m searching for.
i.e. I search for “j” now I can only see “Jessica” and “Jamie” as values. But, this doesn’t change my state, I still see all five until I actually select something from this search, and then they are gone from the state aside from “Jessica,” “Jamie” and my new selection. I’m currently using 1.0.0-rc.3 but I tried switching to re.9 with no resolution.

Here is my code:

<Select.Async
    loadOptions={this.getUsers}
    multi
    disabled={this.state.sending}
    value={this.state.userIds}
    onChange={users => this.setState({ userIds: users })}
    placeholder="Search for Users" />

  userSearch = (search, types, callback) => (
    Fetch.ajax({
     ... get the data
    }).done(({ users }) => {
      const options = this.formatUsers(users)
      callback(null, { options })
    })
  )

  getUsers = (search, callback) => {
    this.userSearch(search, ['Admin'], callback)
  }

  formatUsers = users => (
    _.map(users, user => (
      { label: user.name, value: user.id }
    ))
  )

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:2
  • Comments:7 (1 by maintainers)

github_iconTop GitHub Comments

5reactions
erlanggatjhiecommented, Jan 3, 2018

Hello!

I also had the same issue today and I’m using react-select 1.1.0. Let me try to explain what the problem is. After looking at the source code, I found out that getValueArray and expandValue function in Select component might be the culprit. getValueArray is one of the function that is responsible to render the selected values on the screen.

getValueArray (value, nextProps) {
	const props = typeof nextProps === 'object' ? nextProps : this.props;
	if (props.multi) {
		if (typeof value === 'string') {
			value = value.split(props.delimiter);
		}
		if (!Array.isArray(value)) {
			if (value === null || value === undefined) return [];
			value = [value];
		}
		return value.map(value => this.expandValue(value, props)).filter(i => i);
	}
	var expandedValue = this.expandValue(value, props);
	return expandedValue ? [expandedValue] : [];
}

expandValue (value, props) {
	const valueType = typeof value;
	if (valueType !== 'string' && valueType !== 'number' && valueType !== 'boolean') return value;
	let { options, valueKey } = props;
	if (!options) return;
	for (var i = 0; i < options.length; i++) {
		if (String(options[i][valueKey]) === String(value)) return options[i];
	}
}

When we pass in an array of a string into the value property (this.state.userIds in your case) of the Select element, it will go to this code inside getValueArray:

return value.map(value => this.expandValue(value, props)).filter(i => i);

It will call expandValue function for each element of the value and if we look at the expandValue function, because of the type of value is string, it will go to this code:

for (var i = 0; i < options.length; i++) {
	if (String(options[i][valueKey]) === String(value)) return options[i];
}

And this is where the problem is. It will compare each selected value with the options that are loaded asynchronously and return undefined if the selected value is not present in the options. So in your case, it will return only Jessica and Jamie and the rest of the items will be undefined:

// coming back to this code in getValueArray().
// Here, I replace the map function with your data to clarify what i'm saying
return [undefined, undefined, undefined, { label: 'Jessica', value: 'id1' }, { label: 'Jessica', value: 'id2' }].filter(i => i);

Then all the undefined values will be filtered out and the component will render the remaining two.

I’m not sure how to fix this cleanly and the temporary solution that I had is to not pass in an array of a string into the value props but instead pass in an array of an object that has the same data structure as the options. In your case, I would do:

// where this.state.users are in this format:
// [{ label: 'Jessica', value: 'id1' }, { label: 'Tammy', value: 'id2' }, ...]
<Select.Async
    loadOptions={this.getUsers}
    multi
    disabled={this.state.sending}
    value={this.state.users}
    onChange={users => this.setState({ users: users })}
    placeholder="Search for Users" />

  ...
0reactions
bladeycommented, May 27, 2020

Hello -

In an effort to sustain the react-select project going forward, we’re closing old issues / pull requests.

We understand this might be inconvenient but in the best interest of supporting the broader community we have to direct our limited efforts to maintain the latest 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.

If you feel this issue / pull request 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.

Read more comments on GitHub >

github_iconTop Results From Across the Web

React select remove selected option on search - Stack Overflow
import React from "react"; import Select from "react-select/async"; const CheckboxDropdown = ({ options, defaultValue, loadOptions, ...
Read more >
Advanced - React Select
While React-Select assumes a standard way of filtering the menu on search, ... 'remove-value': (Multiple) Removing a selected option with the remove button ......
Read more >
React-Select-Plus Example - HubSpot
Multiselect Single Value. This example implements custom label and value properties, async options and opens the github profiles in a new window when...
Read more >
chakra-react-select - npm
Once installed, you can import the base select package, the async ... isMulti options={[ { label: "I can't be removed", value: "fixed", ...
Read more >
React Select with options outside - Prepsheets
If isMulti is true then we use the controlShouldRenderValue prop to hide the selected values and loop over the values prop and map...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found