0

I am reading the data from database and displaying it in a autocomplete drop down list. When the user clicks on the input field the data is read from the database and response is fetched using axios. While the data is loading the option value in the autocomplete should be 'Loading'. Once data is loaded then the required values should be displayed. The problem is that once the user clicks on the dropdown and he gets the Loading option. However, even when the data is loaded the options do not change and remain as Loading only. For getting the desired options user has to click again on the input field/drop down. Below is the code.

class Colors extends Component{

        state={
            IsColorListLoaded:false,
            colors_List=[]
        }

        render(){
            const getColors=()=>{

                            //get color list fromthe db using axios
                            //populates the colors_List and sets IsColorListLoaded to true using setState
              axios.get(url,{headers}).then((response) => {

            if(response.data.recordset.length ===0){

                alert ('No data found' );}

                else{

            var colors_list_temp=[];

            

            colors_list_temp=response.data.recordset

            this.setState((prevState) => ({


                ...prevState,

                colors_List: colors_list_temp,

                

            }),()=>{

                this.setState((prevState) => ({


                    ...prevState,

                    IsColorListLoaded:true

                    
                }))

            });

        }       

        

        }, (err) => {

            console.log("Error While Posting Data", err);

        });


                    }

                    return(
                         <div>
                            <input required list="colors" onClick={getColors} 
                             onChange={updateColor}  placeholder="Colors"/>

                            <datalist id="colors" >

                            {!this.state.IsColorListLoaded?<div><option value=" " readonly>Loading</option></div>:

                                    <div>{this.state.colors_List.map((e, key) => { 

                                                        
                                    return <option key={key} value={e.VALUE} >{e.VALUE}</option> })
                                  
                                  }

                                                    

                                    </div>

                                        

                            }

                            </datalist>
                       </div>
                        )  
        }
}

url and headers are declared globally.Hooks cannot be used due to some compatibility issues.

4
  • @RubenSmn that was a part of the code. I have enclosed the code in <div> element now. Initially colors_List is an empty list. So while it is empty IsColorListLoaded remains false. Commented Oct 22, 2022 at 19:11
  • The readonly attribute on the option element is throwing an error, if you don't want the user to select it you can change it to disabled, check here for the docs Commented Oct 22, 2022 at 19:31
  • @RubenSmn still same error Commented Oct 23, 2022 at 2:53
  • 1
    It might be worth posting all of the component as a whole as I think key context is missing here. Especially the contents of getColors Commented Oct 23, 2022 at 4:38

1 Answer 1

0

IsColorListLoaded can be set at the same time you set the colors_List. I also put your (err) functionality into a catch. Also the readonly attribute was still throwing errors since it is not a valid attribute so changed it to disabled

Your updateColor was not present so I added a placeholder to prevent errors.

class Colors extends Component {
  state = {
    IsColorListLoaded: false,
    colors_List: [],
  };

  getColors() {
    //get color list fromthe db using axios
    //populates the colors_List and sets IsColorListLoaded to true using setState
    axios
      .get(url, { headers })
      .then((response) => {
        if (response.data.recordset.length === 0) {
          alert("No data found");
        } else {
          this.setState((prevState) => ({
            ...prevState,
            colors_List: response.data.recordset,
            IsColorListLoaded: true,
          }));
        }
      })
      .catch((err) => {
        console.log("Error While Posting Data", err);
      });
  }

  updateColor() {
    console.log("Update color");
  }

  render() {
    return (
      <div>
        <input
          required
          list="colors"
          onClick={this.getColors}
          onChange={this.updateColor}
          placeholder="Colors"
        />

        <datalist id="colors">
          {!this.state.IsColorListLoaded ? (
            <div>
              <option value=" " disabled>
                Loading
              </option>
            </div>
          ) : (
            <div>
              {this.state.colors_List.map((e, key) => {
                return (
                  <option key={key} value={e.VALUE}>
                    {e.VALUE}
                  </option>
                );
              })}
            </div>
          )}
        </datalist>
      </div>
    );
  }
}

A suggestion could be to fetch the api on componentDidMount so you don't have to wait with fetching until the user clicks the input.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.