sortinousn
sortinousn

Reputation: 647

Render async fetch response as an element in React-Native?

I have an array of data I'm getting back from an API using fetch. I'm trying to parse and render the json response as elements in my app, however I'm not having any luck, how would I go about fixing my code to render my async data as elements?

Here's the data I'm trying to render

class Profile extends React.PureComponent {
    static propTypes = {
    navigation: PropTypes.object,
    handleLogout: PropTypes.func,
    user: PropTypes.object,
  };

  static navigationOptions = {
    headerVisible: true,
    title: 'Profile',
  };

constructor(props) {
    super(props);

    this.state = {
    data: []
    };
  }

componentDidMount() {
fetch("http://10.0.2.2:8080/combined",
{ method: 'get' })
.then(function(response) {
  var data = response.json();
   console.log(data)
   this.setState({ data })

 })
   .catch(function(err) {    }

   );
  };


  logout = () => {
    const callback = () => {
      const resetAction = NavigationActions.reset({
        index: 0,
        actions: [NavigationActions.navigate({ routeName: 'SignIn' })],
      });
      this.props.navigation.dispatch(resetAction);
    };
    this.props.handleLogout(callback);
  };



  jsonData() {
  return this.state.data.map(function(rows, i){
    return(
      <View key={i}>
        <Text>{rows.FIRSTNAME}</Text>
      </View>
    );
  });
}

  render() {

    const { user } = this.props;
    let email;

    return (
      <ContentWrapper>
        <View style={styles.container}>
          <Image style={styles.header} source={images.profileHeader} />
          <View style={styles.body}>
            <Avatar email={email} style={styles.avatar} />
            <Text style={styles.email}>{_.capitalize(email)}</Text>
            {jsonData()}
            <Button
              title="Log out"
              icon={{ name: 'logout-variant', type: 'material-community' }}
              onPress={this.logout}
              style={styles.logoutButton}
            />
          </View>
        </View>
      </ContentWrapper>
    );
  }


}



export default Profile;

Upvotes: 0

Views: 2435

Answers (2)

Andreyco
Andreyco

Reputation: 22862

Remember, response.json() is asynchronous as well and returns Promise, not data as you expect.

Adjust code responsible for fetching to this and you are good to go...

componentDidMount() {
  fetch("http://10.0.2.2:8080/combined", { method: 'get' })
    .then(response => response.json())
    .then(data => {
      this.setState({ data })
    })
   .catch(function(err) {
     // 
   })
}

Upvotes: 3

Matt Aft
Matt Aft

Reputation: 8936

You can set it so it only renders if data has a length:

jsonData = () => (this.state.data.length ? this.state.data.map((rows, i) => (
  <View key={i}>
    <Text>{rows.FIRSTNAME}</Text>
  </View>
)) : null)

Upvotes: 0

Related Questions