1

So I am pulling a list of companies from Firestore and trying to map them into selections in a dropdown list. The companies state is populating right from Firestore, but my options are not being created / updated. How do I get the options to dynamically populate?

My state and db pull:

constructor(props) {
    super(props);
    this.state = {
      db: '',
      companies: [],
      jobs: [],
      company: 'Company',
      job: 'Job'
    };
  }

  componentDidMount() {
    this.db = firestore.firestore();
    this.db.collection("companies")
    .get()
    .then(querySnapshot => {
      const data = querySnapshot.docs.map(doc => doc.data());
      console.log(data);
      this.setState({ companies: data });
    });
  }

Where I attempt to create the options (based on this stack post I found):

createCompanySelections() {
    var company_selections = [];
    if(this.companies) { 
      company_selections = this.companies.map((Name) => <option key={Name}>{Name}</option>);
    }
    return company_selections
  }

Where I try to insert the selections (using materialUI):

<FormControl>
   <InputLabel htmlFor="companies">Companies</InputLabel>
   <NativeSelect
    variant='standard'
    value={this.state.company}
    onChange={this.updateInput}
    inputProps={{
      name: 'company',
    }}
   >
     {this.createCompanySelections()}
  </NativeSelect>
</FormControl>

1 Answer 1

2

// updated answer for a cleaner solution It looks like your component doesn't re-render on that change, so to make sure it does pick up the change just pass new data in render.

constructor(props) {
  super(props);
  this.state = {
    db: '',
    companies: [],
    jobs: [],
    company: 'Company',
    job: 'Job'
  };
 }

 componentDidMount() {
    this.db = firestore.firestore();
    this.db.collection("companies")
    .get()
    .then(querySnapshot => {
      const data = querySnapshot.docs.map(doc => doc.data());
      console.log(data);
      // set copmany options on state, so component re-renders once they are set
      this.setState({ 
        companies: data,
      });

    });
  }

// looks like you always pass an array 
  createCompanySelections(companies) {
     return companies.map((Name) => <option key={Name}>{Name}</option>);
  }

And in Form control do something like:

 {!!this.companies.length && (
    <FormControl>
    <InputLabel htmlFor="companies">Companies</InputLabel>
      <NativeSelect
        variant='standard'
        value={this.state.company}
        onChange={this.updateInput}
        inputProps={{
          name: 'company',
        }}
      >
        {this.createCompanySelections(this.companies)}
      </NativeSelect>
    </FormControl>
  )}
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.