how to populate options for a react select by fetching values from an api to be visible when you click on the select box?

10,194

'App1' is rendering before you actually get the data. One way to fix this is to wait for the data to be fetched then render 'App1', like this:

handleOnchange = async () => {
   await copyOptionsForAsync();
   this.setState({ isSelected: true });
};

Working example in codesandbox: https://codesandbox.io/s/m6wr8zvjj

Share:
10,194
Sachin Kumar
Author by

Sachin Kumar

Updated on December 06, 2022

Comments

  • Sachin Kumar
    Sachin Kumar over 1 year

    I am using react-select for drop downs in my application. Below is my requirement.

    • Select a value from the drop down for the first Select component(second Select is not rendered yet).
    • Basing on the selected value fetch the options for second Select component and render the second Select box.
    • Click in the text area of the second Select.

    • What is happening : I see No Options as the default drop down. I can see the values from the API only when I type something in the box and that matches the default filter criteria.

    What I want to happen : It should display the values that we fetched from the API call.

    const options = [{ label: "first", value: "first" }];
    let options1 = [];
    
    async function copyOptionsForAsync() {
      let response = await fetch("https://jsonplaceholder.typicode.com/todos");
      let data = await response.json();
      data.forEach(element => {
        let dropDownEle = { label: element["title"], value: element };
        options1.push(dropDownEle);
      });
    }
    
    class App extends React.Component {
      constructor() {
        super();
        this.state = {
          isSelected: false
        };
      }
      handleOnchange = () => {
        this.setState({ isSelected: true });
        copyOptionsForAsync();
        console.log(options1);
      };
      render() {
        return (
          <div className="App">
            <Select
              name="option"
              options={options}
              onChange={this.handleOnchange}
            />
            {this.state.isSelected ? <App1 /> : null}
          </div>
        );
      }
    }
    class App1 extends React.Component {
      render() {
        return (
          <div className="App">
            <Select name="options2" options={options1} />
          </div>
        );
      }
    }
    
    const rootElement = document.getElementById("root");
    ReactDOM.render(<App />, rootElement);
    

    This is the link to codesandbox page. Can any one tell me how will I be able to display the options once I click on the select box.

  • Sachin Kumar
    Sachin Kumar over 5 years
    Thanks for the answer. I added console.log in the forEach block and what I observe is the console log in handleOnChange prints the fully populated options1 object, then render for App and then render for App1 and then the console log in the forEach loop. What I don't understand here is if the loop is not completed yet how is it able to print options1 in handleOnChange method.
  • Robert Purcea
    Robert Purcea over 5 years
    After this.setState({ isSelected: true }); runs, App and App1 are rendered. Rendering takes place before copyOptionsForAsync(); finishes fetching the data. As for console.log(option1) - it does not print the data, it prints an empty array. Check out this video: youtube.com/watch?v=8aGhZQkoFbQ to see how async code works in js.
  • Sachin Kumar
    Sachin Kumar over 5 years
    Thanks for the explanation. May be I will check the console log in different browsers to see if there is any difference. You may be correct in saying that empty array is printed as i can only see [] and see the options when I expand. But I think in general if there is data in an array it prints dots and size as well. Will check out the video you have shared. Thank you.