5

I am new to react-native. I'm building up complexity but have gotten stuck on rendering FlatList items from a json list. This was working fine for ListView but not able to figure out what I am missing on FlatList.

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

export default class Movies extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isLoading: true
    }
  }

  componentDidMount() {
    return fetch('https://gnosisdevelopment.com/office/list.json')
      .then((response) => response.json())
      .then((responseJson) => {
        let data_source = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
        this.setState({
          isLoading: false,
          dataSource: data_source.cloneWithRows(responseJson.office_staff),
        }, function() {
          // do something with new state
        });
      })
      .catch((error) => {
        console.error(error);
      });
  }

  render() {
    if (this.state.isLoading) {
      return (
        <View style={{flex: 1, paddingTop: 20}}>
          <ActivityIndicator />
        </View>
      );
    }

    return (
      <View style={styles.container}>
        <FlatList
          data={this.state.dataSource}
          renderItem={({item}) =>
                    <Text style={styles.touchButtonText}>{item.staff_name} </Text>
          }
        />
      </View>
    );
  }
}
const styles = StyleSheet.create({
container: {
    flex:1,
    alignItems: 'center',
    alignContent:'center',
    flexDirection: 'row',
    flexWrap:'wrap',
    justifyContent:'center',
},
touchButton:{
    alignSelf:'center',
    backgroundColor:'#2980b9',
    paddingVertical: 25,
    width:295,
    margin:15,
},
touchButtonText:{
  textAlign:'center',
  color:'#ffffff',
  fontWeight:'bold'
},

})

The text field will be in a touchable and I'll be adding function to the buttons but I wanted to get the listing correct first. Any suggestions are welcome. Thanks for the help :)

https://gnosisdevelopment.com/office/list.json

 {
  "title": "Welcome to our office",
  "description": "Your smart office assistant",
  "office_staff": [
    { "staff_name": "Dr. Bob"},
    { "staff_name": "Dr. Xavior"},
    { "staff_name": "Dr. Sanchez"},
    { "staff_name": "Dr. Robert"},
    { "staff_name": "Dr. Albert"}
  ]
}

UPDATE with new datasource load:

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

    export default class Office extends Component {
      constructor(props) {
        super(props);
        this.state = {
          isLoading: true,
          dataSource: [],
        } 
      }

      componentDidMount() {
          return fetch('https://gnosisdevelopment.com/office/list.json')
            .then((response) => response.json())
            .then((responseJson) => {
             // just setState here e.g.
             this.setState({ dataSource: responseJson.office_staff, isLoading:false,});
            })
            .catch((error) => {
              console.error(error);
            });
        }
      render() {
        if (this.state.isLoading) {
          return (
            <View style={{flex: 1, paddingTop: 20}}>
              <ActivityIndicator />
            </View>
          );
        }

       return (
      <View style={styles.container}>
        <FlatList
          data={this.state.dataSource}
          renderItem={({item}) =><Text style={styles.touchButtonText}>{item.staff_name}</Text>
          }
          keyExtractor={(item, index) => index}
        />
      </View>
    );
  }
}
    const styles = StyleSheet.create({
    container: {
        flex:1,
        alignItems: 'center',
        alignContent:'center',
        flexDirection: 'row',
        flexWrap:'wrap',
        justifyContent:'center',
    },
    touchButton:{
        alignSelf:'center',
        backgroundColor:'#2980b9',
      paddingVertical: 25,
        width:295,
        margin:15,
    },
    touchButtonText:{
      textAlign:'center',
      color:'#ffffff',
      fontWeight:'bold'
    },

    })

Final working version:

import React, { Component } from 'react';
import { ActivityIndicator, Text, View, StyleSheet,TouchableOpacity, FlatList  } from 'react-native';

export default class Office extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isLoading: true,
      dataSource: [],
    }
  }

  componentDidMount() {
      return fetch('https://gnosisdevelopment.com/office/list.json')
        .then((response) => response.json())
        .then((responseJson) => {
         // just setState here e.g.
         this.setState({ dataSource: responseJson.office_staff,isLoading: false });
        })
        .catch((error) => {
          console.error(error);
        });
    }
  render() {
    if (this.state.isLoading) {
      return (
        <View style={{flex: 1, paddingTop: 20}}>
          <ActivityIndicator />
        </View>
      );
    }

    return (
      <View style={styles.container}>
        <FlatList
          data={this.state.dataSource}
          renderItem={({item}) =><Text>{item.staff_name}</Text>}
          keyExtractor={(item, index) => index}
        />
      </View>
    );
  }
}
const styles = StyleSheet.create({
container: {
    flex:1,
    alignItems: 'center',
    alignContent:'center',
    flexDirection: 'row',
    flexWrap:'wrap',
    justifyContent:'center',
},
touchButton:{
    alignSelf:'center',
    backgroundColor:'#2980b9',
  paddingVertical: 25,
    width:295,
    margin:15,
},
touchButtonText:{
  textAlign:'center',
  color:'#ffffff',
  fontWeight:'bold'
},

})
2
  • can you give us an example on how your json looks like? Commented Nov 20, 2017 at 9:46
  • Adding to my question Commented Nov 20, 2017 at 9:48

1 Answer 1

2

You don't need to provide a dataSource like that.

  constructor(props) {
    super(props);
    this.state = {
      isLoading: true,
      dataSource: [], 
    }
  }
componentDidMount() {
    return fetch('https://gnosisdevelopment.com/office/list.json')
      .then((response) => response.json())
      .then((responseJson) => {
       // just setState here e.g. 
       this.setState({ 
           dataSource: responseJson.office_staff,
           isLoading: false,  
       });         
      })
      .catch((error) => {
        console.error(error);
      });
  }
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks. I'm trying it with my code but it just keeps loading. It was a bit slow before but now its been a few minutes and I still have the loading symbol. I'll add what I have now in case I missed something.
@James sorry i forgot to set isLoading to false. I edited my answer ;)
That worked. Thank you. Looks much more straight forward. I'm still working on the issue of nothing resolving from my list.
@James you’re welcome. Could you please mark my answer as correct? Thanks :)
Tim, I really appreciate your feedback and I gave it a ^ , but it didn't resolve my issue which is list items not loading. I apologize but can't mark it correct for this question.
|

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.