0

enter image description hereI am trying to setState of two different sate(options1 ad options2) in my component with data gotten from firebase. The data in the state of the component is to be used for a dependent drop-down. I have been able to setState with the new firebase data(I know this because I see that the state of my component is the data from my database using the react developer tools). However, the data is not being rendered on the dropdown. Is there something I am doing wrong or should be doing.

class Impairement extends Component {
      constructor() {
        super();
        this.state = {
          name: "React",
          selectedOption: {},
          selectedOption2: {},
          options1: [],
          options2: []
        };
      }

      componentDidMount() {
        this.getnewData();
      }
      //firebase fetch
      getnewData() {
        var rootRef = firebase
          .database()
          .ref()
          .child("test");
        var opt = [];
        rootRef.on("child_added", snapshot => {
          opt.push({
            value: snapshot.val().value,
            label: snapshot.val().label
          });
        });

        var rootRef = firebase
          .database()
          .ref()
          .child("test2");
        var optio = [];
        rootRef.on("child_added", snapshot => {
          optio.push({
            label: snapshot.val().label,
            link: snapshot.val().link,
            value: snapshot.val().value
          });
        });

        this.setState({
          options1: opt
        });
        this.setState({
          options2: optio
        });
      }

      handleChange1 = selectedOption => {
        this.setState({ selectedOption });
      };

      handleChange2 = selectedOption => {
        this.setState({ selectedOption2: selectedOption });
      };

      render() {
        const filteredOptions = this.state.options2.filter(
          o => o.link === this.state.selectedOption.value
        );

        return (
          <div>
            <p>Select Domain</p>
            <Select
              name="form-field-name"
              value={this.state.selectedOption.value}
              onChange={this.handleChange1}
              options={this.state.options1}
            />
            <p>Then Subdomain</p>
            <Select
              name="form-field-name"
              value={this.state.selectedOption2.value}
              onChange={this.handleChange2}
              options={filteredOptions}
            />
          </div>
        );
      }
    }

    export default Impairement;
  • is Select a custom component ? Show us your code. If it is the html element, it should be `select` (lowercase) and you should iterate to create all the options tags. See https://stackoverflow.com/questions/21733847/react-jsx-selecting-selected-on-selected-select-option – Gonzalo.- Jul 31 '18 at 19:32
  • 1
    the opt.push and optio.push are being done within async callbacks. The state is being set when the opt and optio arrays are not populated – Martín Zaragoza Jul 31 '18 at 19:42
  • @Gonzalo.- yes Select is a custom package I downloaded. The thing is it works when i hardcode the value of options1 and options2 state. However, when I setState to the firebase data it doesnt work anymore. – yetunde okunola Jul 31 '18 at 19:47
  • @MartínZaragoza I dont understand. I see that the state updates to the array from firebase, it just doesn't just render. – yetunde okunola Jul 31 '18 at 19:51
  • Yetunde, check @Gonzalo.-'s answer down below – Martín Zaragoza Jul 31 '18 at 19:59

1 Answers1

0

You have to setState inside your event function

currently you're not doing it, those events are asynchronous so when you do setState now, the arrays are empty

rootRef.on("child_added", snapshot => {
     let element = {
            label: snapshot.val().label,
            link: snapshot.val().link,
            value: snapshot.val().value
          };    
    this.setState(prevState => ({ options1: [...prevState.options1, element]  })
});
// notice I store the second reference in another variable
rootRef2.on("child_added", snapshot => {
          let element = {
            label: snapshot.val().label,
            link: snapshot.val().link,
            value: snapshot.val().value
          });
       this.setState(prevState => ({ options2: [...prevState.options2, element]  })
});

furthermore, I think you can rewrite the code a bit because you're using the same variable with two different instances of the same event. But this at least should solve your initial problem

Gonzalo.-
  • 12,512
  • 5
  • 50
  • 82