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.

Select.Async - isLoading is true after option selected

See original GitHub issue

There is a loading circle present most of the time when viewing my Select.Async component. The circle seems to go away only when the following conditions are true:

  1. The text in the input is not found in the cache
  2. There are matching dropdown entries for the text in the input

Even if those conditions are met, as soon as I select an option, the loading circle returns.

It’s difficult to pin down the exact circumstances because the very act of setting breakpoints interferes with the asynchronous nature of this component. At any rate, my loading circle persists almost constantly, making it look like there’s a search in progress when in fact results have long since been loaded and an option has been selected.

The component that renders Select.Async looks like this:

export class SelectAsync extends React.Component {
  static propTypes = {
    field: PropTypes.object.isRequired,
    id: PropTypes.string.isRequired,
    label: PropTypes.string.isRequired,
    load: PropTypes.func.isRequired,
    labelKey: PropTypes.string,
    valueKey: PropTypes.string,
    onChange: PropTypes.func.isRequired,
    serverErrors: PropTypes.array
  };

  labelKey() {
    return this.props.labelKey || 'label';
  }

  valueKey() {
    return this.props.valueKey || 'value';
  }

  callback(option) {
    let noop = (option) => { }
    let f = this.props.onChange || noop;
    f(option);
  }

  handleBlur(field) {
    field.onBlur(field.value);
  }

  handleChange(option) {
    let val = option[this.valueKey()] || null;
    this.props.field.onChange(val);
    this.callback(option);
  }

  render() {
    const {
      field,
      id,
      label,
      load,
      onChange,
      serverErrors
    } = this.props;

    return (
      <FormField {...this.props}>
        <Select.Async
          id={id}
          loadOptions={_.debounce(load, 500)}
          labelKey={::this.labelKey()}
          valueKey={::this.valueKey()}
          value={field.value}
          {...field}
          onChange={::this.handleChange}
          onBlur={() => this.handleBlur(field)} />
      </FormField>
    );
  }
}

This component takes a load property, which is the function used to do the search:

export function lookupProducts(input) {
  return api.searchProducts(input).then((response) => {
    return response.data.products;
  }).then((json) => {
    return {
      options: json
    };
  });
}

Everything works fine except for isLoading being reset to true even when there is no AJAX call in progress and an option has been chosen.

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Reactions:5
  • Comments:10 (1 by maintainers)

github_iconTop GitHub Comments

4reactions
saranshbansalcommented, Sep 21, 2017

Don’t know if this is helpful but I faced a similar issue.

Basically, when I select an option from the dropdown list, the circle starts spinning for no reason.

Here is my loadOptions method:

getOptions(input, callback) {
      let options = [];
      let optionsMap = [];
      const rawKiList = [];
      if (input !== null && input.trim() !== '') {
        setTimeout(() => {
          callback(null, **api.getKiSuggestions(input, this.props.gcomUsrId, (response)** => {
            if (response != null && response.body != null) {
              const resultNode = response.body;
              Object.keys(resultNode).map((i) => {
                rawKiList.push(
                  resultNode[i]
                );
              });
              options = this.createOptionsFromApi(rawKiList);
              optionsMap = this.createSuggestionsMap(rawKiList);
              // set options {value,label} and optionsMap [{id:id, obj:obj}] in state
              this.setState({
                options,
                optionsMap
              });
            }
          }));
        }, 100);
      } else {
          **// Send a null callback to disable loading icon.
          callback(null);**
      }
    }

I just handled the case where it executes loadOptions unnecessarily after selecting an option (by passing null callback). Plus I added a onBlurResetsInput= false to the code:

<Select.Async
              options={options}
              value={tags}
              loadOptions={this.getOptions}
              onChange={this.handleTagListUpdates}
              filterOptions={(suggestions) => { return suggestions; }}
              multi={true}
              autoload={false}
              cache={false}
              clearable={false}
              onSelectResetsInput={false}
              closeOnSelect={false}
              **onBlurResetsInput={false}**
            />

And it works perfectly!

PS: ** refers to highlighted code

1reaction
moog16commented, Sep 16, 2016

What I tried doing is call the callback method in the loadOptions method on init. So something like this:

      if(!this.state.hasSelectInit) {
        this.setState({ hasSelectInit: true });
        callback(null, {options: [], complete: false});
      }

This stopped it from happening.

Read more comments on GitHub >

github_iconTop Results From Across the Web

React-Select Async loadOptions is not loading options properly
The example on github specified that 'leading:true' should be added as an option value as well. In my situation this wasn't needed. After...
Read more >
Async - React Select
A flexible and beautiful Select Input control for ReactJS with multiselect, autocomplete and ajax support.
Read more >
How To Handle Async Data Loading, Lazy Loading, and Code ...
This tutorial will explain how to avoid this with a special Hook called useEffect , which will run functions only when specific data...
Read more >
react-select-old - npm
Multiselect options. You can enable multi-value selection by setting multi={true} . In this mode: Selected options will be removed from the ...
Read more >
Select - Examples - Components - Atlassian Design System
Allows the user to select a single item from a dropdown list of options. ... Setting isClearable to true lets users clear their...
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