1

I have collapsible listview, every item is a touchablehighlight , whenever user clicks on them, i need to redirect user to another page, with some id (arguments, touchablehighlight's id)

for debugging and testing purpose, before redirecting user to a page (i don't know exactly how to do that yet), first i tried to print the id in console. but problem is whichever button you click on it, it will print the last item's id. (last item in array).

Any solutions? what's my mistake?

var Accordion = require('react-native-accordion');

class Courses extends Component {

  constructor(props) {
        super(props);
        this.state = {
          dataSource: new ListView.DataSource({
            rowHasChanged: (row1, row2) => row1 !== row2,
          }),
          loaded: false,
        };
    }

  fetchData() {
// fetching data
  }

  componentDidMount() {
    this.fetchData();
  }

  render(){
    if (!this.state.loaded) {
      return this.renderLoadingView();
    }

    return (
      <View style={{
        flex: 1
      }}>
      <ListView
        dataSource={this.state.dataSource}
        renderRow={this.renderRow}
        style={styles.listView}
      />
      </View>
    );
  }

  renderRow(data) {

    var header = (
      <View>
          <View style={styles.rowContainer}>
            <View  style={styles.textContainer}>
              <Text style={styles.title}>{data.nid}</Text>
              <Text style={styles.description} numberOfLines={0}>{data.title}</Text>
            </View>
          </View>
          <View style={styles.separator}></View>
    </View>
    );
///////////
    var content = [];
    for(var x=0; x < Object.keys(data.course).length; x++){
      var title = data.course[x].title;
      var course_id = data.course[x].course_id;
      content.push(
        <TouchableHighlight
        underlayColor='#e3e0d7'
        key={x}
        onPress={() => {
          console.log(title);   ///<<<<<< here is the problem >>>>>>
        }}
        style={styles.child}
        >
        <Text style={styles.child}>
        {data.course[x].title}
        </Text>
        </TouchableHighlight>
      );
    }
    var clist = (
      <View style={styles.rowContainer}>
      {content}
      </View>
    );
////////////
    return (
      <Accordion
        header={header}
        content={clist}
        easing="easeOutCubic"
      />
    );
  }

  renderLoadingView() {
    return (
      <View style={styles.loading}>
        <Text style={styles.loading}>
          Loading Courses, please wait...
        </Text>
      </View>
    );
  }
}

module.exports = Courses;

I tried to define a function, just before Render() function like this :

rowPressed(){
    console.log('row pressed');
  }

  render(){
    if (!this.state.loaded) {
      return this.renderLoadingView();
    }

And i called it like this :

var content = [];
    for(var x=0; x < Object.keys(data.course).length; x++){
      var title = data.course[x].title;
      var course_id = data.course[x].course_id;
      content.push(
        <TouchableHighlight
        underlayColor='#e3e0d7'
        key={x}
        onPress={ () => this.rowPressed() }
        style={styles.child}
        >
        <Text style={styles.child}>
        {data.course[x].title}
        </Text>
        </TouchableHighlight>
      );
    }
    var clist = (
      <View style={styles.rowContainer}>
      {content}
      </View>
    );

but it gives error that : Cannot read property 'rowPressed' of null

I tried adding this to constructor but it didnt even help : this.rowPressed = this.rowPressed.bind(this)

also adding bind to onpress didnt help :

onPress={ () => this.rowPressed().bind(this) }
Ata Mohammadi
  • 3,430
  • 6
  • 41
  • 69

1 Answers1

2

Try doing this:

for(let x=0; x < Object.keys(data.course).length; x++){}

Do this in the renderRow the first of the two ways you have it written above.

This way x should be scoped correctly.

Nader Dabit
  • 52,483
  • 13
  • 107
  • 91