1

I am trying to render input data within a state into a ListView. I get a TypeError: undefined is not an object.

import React, { Component } from 'react';
import { View, Text, Picker, StyleSheet, ListView } from 'react-native'

class BeerPicker extends Component {
  constructor(props){
      super(props);
      this.state = {
          beer = []
          dataSource: new ListView.DataSource({
              rowHasChanged: (row1, row2) => row1 !== row2,
          }).cloneWithRows(['string1', 'string2', 'string3']),
      };
      this.addBeer = this.addBeer.bind(this);
  }
  addBeer(itemValue, itemIndex){ 
    this.setState({
        beer: [...this.state.beer, itemValue]
    });
  }

  renderRow(data) {
    return (
      <Text>{`\u2022 ${data}`}</Text>
    );
  }

   render() {
      return (
         <View>
            <Picker selectedValue = {this.state.dataSource} onValueChange = {this.addBeer}>
               <Picker.item label = 'Choose Beer' value = 'none' />
               <Picker.Item label = "IPA" value = "ipa" />
               <Picker.Item label = "Pilsner" value = "pilsner" />
               <Picker.Item label = "Stout" value = "stout" />
            </Picker>
            <ListView
            dataSource={this.state.beer}
            renderRow={this.renderRow}
            />

         </View>
      )
   }
}
export default BeerPicker;

const styles = StyleSheet.create({
   text: {
      fontSize: 30,
      alignSelf: 'center',
      color: 'black'
   }
})

Before I had my state as just an empty array with the addBeer function binded to the constructor. Now I want to make that data render into a listview but now it doesnt work. Do I have to have the datasource binded to the constructor as well?

4
  • Hi, Unless I'm missing something, this.state.beer does not exist in the state since it has not been initialized in the constructor. Commented Nov 23, 2017 at 20:42
  • apologies. It was supposed to be an empty array Commented Nov 23, 2017 at 20:45
  • so that was the problem then? Commented Nov 23, 2017 at 20:46
  • no I am still getting an unexpected token error in the state. I am having issues wrapping picker and listview together to work unanimously. I fixed the above code to show what I have Commented Nov 23, 2017 at 20:48

1 Answer 1

1

There is something missing about your code.

Firstly, there is an extra coma after the rowHasChanged callback.

Secondly, Picker expects as selectedValue just one value, you are passing a datasource.

Lastly, ListView expects a dataSource, but you are passing an array.

Try this snippet:

constructor(props){
  super(props);

  //This could be a constant out of your component
  this.ds = new ListView.DataSource({rowHasChanged: (row1, row2) => row1 !== row2});

  this.state = {
    beer: [],
    beerDataSource: this.ds.cloneWithRows([]),
    dataSource: this.ds.cloneWithRows(['string1', 'string2', 'string3']) //It seems to be not needed...
  };

  this.addBeer = this.addBeer.bind(this);
}

addBeer(itemValue, itemIndex){ 
  let newBeerArray = [...this.state.beer, itemValue];
  this.setState({
    beer: newBeerArray,
    beerDataSource: this.ds.cloneWithRows(newBeerArray);
  });
}

render() {
  return (
    <View>
      <Picker selectedValue = {this.state.dataSource/* revise this, this should be a unique value */} onValueChange = {this.addBeer}>
        <Picker.item label = 'Choose Beer' value = 'none' />
        <Picker.Item label = "IPA" value = "ipa" />
        <Picker.Item label = "Pilsner" value = "pilsner" />
        <Picker.Item label = "Stout" value = "stout" />
      </Picker>
      <ListView
        dataSource={this.state.beerDataSource}
        renderRow={this.renderRow}/>
    </View>
  )
}

Here you will find an improved version of your component. I haven't tested, but It should work fine. Let me know whatever you need.

import React, { Component } from 'react';
import { View, Text, Picker, StyleSheet, ListView } from 'react-native'

const ds = new ListView.DataSource({rowHasChanged: (row1, row2) => row1 !== row2});

export default class BeerPicker extends Component {
    constructor(props){
      super(props);

      this.state = {
        beer: [],
        beerDataSource: ds.cloneWithRows([]),
        dataSource: ds.cloneWithRows(['string1', 'string2', 'string3']), //It seems to be not needed...
        items: [
          {label: 'Choose Beer', value: 'none'}, 
          {label: 'IPA', value: 'ipa'}, 
          {label: 'Pilsner', value: 'pilsner'}, 
          {label: 'Stout', value: 'stout'}
        ],
        selectedItem: 'none'
      };

      this.addBeer = this.addBeer.bind(this);
    }

    addBeer(itemValue, itemIndex){ 
      let newBeerArray = [...this.state.beer, itemValue];
      this.setState({
        beer: newBeerArray,
        selectedItem: itemValue,
        beerDataSource: ds.cloneWithRows(newBeerArray);
      });
    }

    renderRow(data) {
      return (
        <Text>{`\u2022 ${data}`}</Text>
      );
    }

    render() {
      let items = this.state.items.map((item, index) => {
        return (<Picker.item label={item.label} value={item.value} key={index}/>);
      });

      return (
        <View>
          <Picker selectedValue={this.state.selectedItem} onValueChange = {this.addBeer}>
            {items}
          </Picker>
          <ListView
            dataSource={this.state.beerDataSource}
            renderRow={this.renderRow}/>
        </View>
      )
    }
}

const styles = StyleSheet.create({
   text: {
      fontSize: 30,
      alignSelf: 'center',
      color: 'black'
   }
});
Sign up to request clarification or add additional context in comments.

1 Comment

Thank You. Your improved version of this component is great and now I understand a little bit more about Picker and ListView. This is my first real tackle on a react native application and I am happy the community on Stackoverflow and help contribute!

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.