Search code examples
javascriptreactjsasync-awaitaxiosdropdown

REACT - Dropdown values not updating dynamically


I am new to React so this question might be a little dumb. I am trying to get the dropdown values from backend. The problem I'm facing is that the program is not filling the list with the items even after the async-await function returns the items. Any help would be appreciated.

Code for loading data from backend:-

getDataSources = async () => {
    try {
        return await axios.post("http://localhost:5000/configure_get_sources",
            {
                headers: {
                    "content-type": "application/json"
                }
            }
        );
    }
    catch (e) {
        console.log(e);
    }
};

For the dropdown, I have the code mentioned below:-

        var selectSources = [];

        this.getDataSources().then((res) => {
            for (var i = 0; i < res.data.length; i++) {
                selectSources.push("<option value='" + res.data[i] + "'>" + res.data[i] + "</option>");
            };
        });

    

    return (
             <div className="container">
                  <div className="row">
                       <label className="col-md-4" >Data Source: </label>
                           <select className="col-md-7">
                            {
                              selectSources.map(id =>
                                <option key={id} value={id}>{id}</option>
                              )
                            }
                           </select>
                   </div>
              </div
      );

Solution

  • You'll need to save the options in state in order to re-render the component upon retrieval of the options. Also, you should grab the options in componentDidMount lifecycle method. Try out something like this:

    Add state

        this.state = {
            options: []
        }
    

    Use componentDidMount

    componentDidMount() {
        axios.post("http://localhost:5000/configure_get_sources",
            {
                headers: {
                    "content-type": "application/json"
                }
            }
        ).then(res => {
           this.setState({options: res.data});
        }); 
    
    }
    

    This is assuming that res.data is returned as an array, and not an object containing an array.

    Render method

    let renderedOptions = this.state.options.map((item, i) => {
          return (
              <option value={item} key={i}>{item}</option>
           )
     });
    
    
    
    return (
             <div className="container">
                  <div className="row">
                       <label className="col-md-4" >Data Source: </label>
                           <select className="col-md-7">
                            { renderedOptions }
                           </select>
                   </div>
              </div
      );