2

I can't display json data in listview. I get json data in console.log but not in listview isLoading is always on false. I dont get any errors .catch(error => console.warn("error")). Result on screen is first View because this.state.isLoading is false.

Here is a code:

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

var productArray = [];

class ListViewDemo extends Component {
   constructor(props) {
    console.warn("constructor");
    super(props);
    var dataSource = new ListView.DataSource({rowHasChanged:(r1,r2) => r1.guid != r2.guid});
   this.state = {
      dataSource: dataSource.cloneWithRows(productArray),
     isLoading:true
   }
 }

  componentDidMount() {
    console.warn("componentDidMount");
    this.getTheData(function(json){
     productArray = json;
      console.warn(productArray);
     this.setState = ({
       datasource:this.state.dataSource.cloneWithRows(productArray),
       isLoading:false
     })
    }.bind(this));   
     console.warn("component ->  " + this.state.isLoading);
  }

  getTheData(callback) {
    console.warn("callback");
    var url = "https://raw.githubusercontent.com/darkarmyIN/React-Native-DynamicListView/master/appledata.json";
fetch(url)
     .then(response => response.json())
     .then(json => callback(json))
     .catch(error => console.warn("error"));
   }

  renderRow(rowData, sectionID, rowID) {
    console.warn("renderRow");
    return (
        <TouchableHighlight underlayColor='#dddddd' style={{height:44}}>
         <View>
         <Text style={{fontSize: 20, color: '#000000'}} numberOfLines={1}>{rowData.display_string}</Text>
         <Text style={{fontSize: 20, color: '#000000'}} numberOfLines={1}>test</Text>
         <View style={{height: 1, backgroundColor: '#dddddd'}}/>
        </View>
    </TouchableHighlight>
);
}

   render() {
   console.warn("render" + this.state.isLoading);
   var currentView = (this.state.isLoading) ? <View style={{height: 110, backgroundColor: '#dddddd'}} /> : <ListView dataSource={this.state.dataSource} renderRow={this.renderRow.bind(this)} enableEmptySections={true}/>
   return(
     <View>
       {currentView}
     </View>
   );
  }
}

// App registration and rendering
AppRegistry.registerComponent('AwesomeProject', () => ListViewDemo);

2 Answers 2

2

I see a couple of mistakes here.

In your componentDidMount, you are setting datasource intead of dataSource:

  componentDidMount() {
    console.warn("componentDidMount");
    this.getTheData(function(json){
     productArray = json;
      console.warn(productArray);
     this.setState = ({
       //datasource:this.state.dataSource.cloneWithRows(productArray),
       dataSource:this.state.dataSource.cloneWithRows(productArray),
       isLoading:false
     })
    }.bind(this));   
     console.warn("component ->  " + this.state.isLoading);
  }

That's why you're not being able to render, because dataSource is never populated. It is just a little spelling mistake.

You are probably not getting into the second then in your getTheData method because you are not returning a Promise:

getTheData(callback) {
  console.warn("callback");
  var url = "https://raw.githubusercontent.com/darkarmyIN/React-Native-DynamicListView/master/appledata.json";
  fetch(url)
     //.then(response => response.json())
     .then(response => return response.json())
     .then(json => callback(json))
     .catch(error => console.warn("error"));
   }

Your are making a mistake with your setState, your are assigning it instead of calling it:

 //this.setState = ({
 //  datasource:this.state.dataSource.cloneWithRows(productArray),
 //  isLoading:false
 //})

 this.setState({
   dataSource:this.state.dataSource.cloneWithRows(productArray),
   isLoading:false
 })

Let me know if it works.

Sign up to request clarification or add additional context in comments.

5 Comments

Ok, let's try something, change your renderRow from renderRow(rowData, sectionID, rowID) to renderRow(rowData) and bind it in the constructor this.renderRow = this.renderRow.bind(this);. And put into a View your TouchableHighlight in the renderRow method.
same thing, the problem is that isLoading is alway on true when i log it
change your getData from .then(response => response.json()) to .then(response => return response.json()) . If you dont put return you are not going to enter in the second then.
Your setState is wrong, your are setting it instead of calling it. Check last update to my answer,
Yes, setState was the problem, thanks a lot for your time
1

You are setting the function setState instead of calling it

this.setState = ({
    datasource:this.state.dataSource.cloneWithRows(productArray),
    isLoading:false
})

should be

this.setState({
    datasource:this.state.dataSource.cloneWithRows(productArray),
    isLoading:false
})

2 Comments

Thanks man , it solved my problem .. i spend few hours on this error
Yep, that's happen... Do you understand what was your problem?

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.