2

I am trying to load a list from firebase to a dropdown menu. I'm getting:

TypeError: undefined is not an object (evaluating 'this.state.dataSource.map')

Please advise what am I doing wrong

export default class GenderDropdownComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            dataSource: []
        };
    }
    async get_firebase_list(){
        var items = [];
        firebase.database().ref('lists/gender').on('value', function(snapshot) {
            snapshot.forEach(function(childSnapshot) {
              var childKey = childSnapshot.key;
              var childData = childSnapshot.val();
              items.push(childData);
            }); 
            console.log("items_load: " + items);
            return items;
        });
    }
    async componentWillMount(){
        this.setState({
            dataSource : await this.get_firebase_list()
        })
        console.log("items: " + this.state.dataSource);
    }

    render() {
        return (
            <Picker
                onValueChange={(itemValue, itemIndex) => this.setState({gender: itemValue})}>
                {this.state.dataSource.map((item, index) => {
                    return (<Picker.Item label={item} value={index} key={index}/>) 
                })}
            </Picker>
        );
    }
}
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • 1
    Your `get_firebase_list` function is returning `undefined`, you can set state inside `get_firebase_list` function instead of returning `items` from there. – Prasun Feb 25 '18 at 10:09

1 Answers1

1

You're not returning anything from get_firebase_list right now. The return items you have in there, only returns from function(snapshot) {.

You need to change the code to bubble up the return. IIRC that should be as simple as:

async get_firebase_list(){
    return firebase.database().ref('lists/gender').once('value').then(function(snapshot) {
        var items = [];
        snapshot.forEach(function(childSnapshot) {
          var childKey = childSnapshot.key;
          var childData = childSnapshot.val();
          items.push(childData);
        }); 
        console.log("items_load: " + items);
        return items;
    });
}

I highly recommend also reading Doug's blog post on Firebase's asynchronous APIs.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807