Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filter ListView data in react native

I am trying to write a fliter for my List View in react native. But It is not working , and I don't know why. Here is my Class -

import {
  AppRegistry,
  Image,
  ListView,
  StyleSheet,
  Text,
  TextInput,
  Navigator,
  TouchableHighlight,
  TouchableOpacity,
  filter,
  View
} from 'react-native';
var REQUEST_URL = GLOBAL.STATES_URL + '?apikey=' + GLOBAL.API_KEY;

class MainPage extends Component {
    
  constructor(props) {
    super(props);
    this.state = {
      dataSource: new ListView.DataSource({
        rowHasChanged: (row1, row2) => row1 !== row2,
      }),
      loaded: false,
      searchText: '',
      state: '',
    };
  }
  
  componentDidMount() {
    this.fetchData();
  }
  
  componentDidUpdate() {
    if (this.state.searchText === '') {
      this.fetchData();
    }
  }
  
  filterStates(searchText, states) {
    var text = searchText.toLowerCase();
    var rows = [];
   
   for (var i=0; i < states.length; i++) {
     var stateName = states[i].name.toLowerCase();
     if(stateName.search(text) !== -1){
         rows.push({
              name : states[i].name,
          });
     }
   }
       
    this.setState({
       dataSource: this.state.dataSource.cloneWithRows(rows),
       loaded : true,
     });
  }
  
  fetchData() {
    fetch(REQUEST_URL)
      .then((response) => response.json())
      .then((responseData) => {
        this.setState({
          dataSource: this.state.dataSource.cloneWithRows(responseData),
          loaded: true,
        });
      })
      .done();
  }
 
  setSearchText(event){
    var searchText = event.nativeEvent.text;
    this.setState({searchText});

    fetch(REQUEST_URL)
    .then((data) => {
          this.filterStates(searchText, data);    
    })
    .done();
 }
  
    
  render() {
    return (
      <Navigator
          renderScene={this.renderScene.bind(this)}
          navigator={this.props.navigator}
          navigationBar={
            <Navigator.NavigationBar style={{backgroundColor: '#246dd5'}}
                routeMapper={NavigationBarRouteMapper} />
          }
         />
    );
  }
  
  
  renderScene(route, navigator) {
    if (!this.state.loaded) {
      return this.renderLoadingView();
    }

    return (
      <View style={styles.combo}>
      
       <TextInput
         style={styles.searchBar}
         value={this.state.searchText}
         onChange={this.setSearchText.bind(this)}
         placeholder='Search' />   
      <ListView
        dataSource={this.state.dataSource}
        renderRow={this.renderState.bind(this)}
        // renderScrollComponent={props => <RecyclerViewBackedScrollView {...props} />}
        renderSeparator={(sectionID, rowID) => <View key={`${sectionID}-${rowID}`} style={styles.separator} />}
        style={styles.listView}
      />
      </View>
      
    );
  }
  
  renderLoadingView() {
    return (
      <View style={styles.container}>
        <Text>
          Loading States...
        </Text>
      </View>
    );
  }

  renderState(state,route,navigator) {
    return (
      <TouchableHighlight onPress={this.gotoPersonPage.bind(this,state)}>
         <View style={styles.row}> 
             <View style={styles.container}>
                   <Text style={styles.name}>{state.name}</Text>
             </View>
         </View>
      </TouchableHighlight>
   
    );
  }
  
  
  gotoPersonPage(state) {
    this.props.navigator.push({
      id: 'PersonPage',
      name: 'PersonPage',
      data: {name:state.name , abbreviation:state.abbreviation},
    });
  }
}

Can Anybody please tell that what is the issue in the above code, and solution for that issue. Thanks in advance.

like image 226
Jatin Kinra Avatar asked Jun 02 '16 09:06

Jatin Kinra


1 Answers

Try setting up the new ListView.DataSource({ rowHasChanged: (row1, row2) => row1 !== row2 outside of the component:

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

class MainPage extends Component {
  this.state = {
    dataSource: new ListView.DataSource({
      rowHasChanged: (row1, row2) => row1 !== row2,
    }),
    loaded: false,
    searchText: '',
    state: '',
  };
}

Then setting the state like this:

filterStates(searchText, states) {
    ...

    this.setState({
       dataSource: ds.cloneWithRows(rows),
       loaded : true,
     });
  }

and this:

fetchData() {
    fetch(REQUEST_URL)
      .then((response) => response.json())
      .then((responseData) => {
        this.setState({
          dataSource: ds.cloneWithRows(responseData),
          loaded: true,
        });
      })
      .done();
}
like image 160
Nader Dabit Avatar answered Oct 06 '22 05:10

Nader Dabit