Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access array of objects to display in React Native Text component

I’m having trouble accessing an array of objects in my JSON data to display in a React Native Text component.

JSON data

{
    "name": "Pizza Joint",
    "when": [{
        "day": ["Sat", "Sun"],
        "start_time": "11:00",
        "end_time": "23:00"
    }]
}

Code

<View style={styles.container}>
    <Text style={styles.name}>{venue.name}</Text>
    <Text style={styles.time}>{venue.when[0].start_time}</Text>
</View>

This throws the error Undefined is not an object (evaluating 'venue.when') which I don't understand since console.log(type of venue.when) returns object.

How can I access the when object properties here?

Additional notes

I copied the app structure from this tutorial.

Here is VenueList.js:

'use strict';

var React = require('react-native');
var VenueDetail = require('./VenueDetail');

var {
    Image,
    StyleSheet,
    Text,
    View,
    Component,
    ListView,
    TouchableHighlight,
    ActivityIndicatorIOS
   } = React;

var styles = StyleSheet.create({
    container: {
        flex: 1,
        flexDirection: 'row',
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
        padding: 10
    },
    thumbnail: {
        width: 53,
        height: 81,
        marginRight: 10
    },
    rightContainer: {
        flex: 1,
    },
    title: {
        fontSize: 20,
        marginBottom: 8
    },
    author: {
        color: '#656565'
    },
    separator: {
        height: 1,
        backgroundColor: '#dddddd'
    },
    listView: {
           backgroundColor: '#F5FCFF'
       },
   loading: {
       flex: 1,
       alignItems: 'center',
       justifyContent: 'center'
   }
});

// var REQUEST_URL = 'https://www.googleapis.com/books/v1/volumes?q=subject:fiction';
var REQUEST_URL = 'http://apib.miniguide.es/wall/today';

class VenueList extends Component {

  render() {
    if (this.state.isLoading) {
      return this.renderLoadingView();
    }
    console.log(this.state.dataSource);

    return (
      <ListView
        dataSource={this.state.dataSource}
        renderRow={this.renderVenue.bind(this)}
        style={styles.listView}
      />
    );
  }

  renderLoadingView() {
    return (
      <View style={styles.loading}>
        <ActivityIndicatorIOS
          size='large'/>
          <Text>
            Loading venues...
          </Text>
      </View>
    );
  }

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

  componentDidMount() {
    this.fetchData();
  }

  fetchData() {
    fetch(REQUEST_URL)
    .then((response) => response.json())
    .then((responseData) => {
      this.setState({
        dataSource: this.state.dataSource.cloneWithRows(responseData),
        isLoading: false
      });
    })
    .done();
  }

  renderVenue(venue) {
    console.log(venue);
    return (
      <TouchableHighlight onPress={() => this.showVenueDetail(venue)} underlayColor='#dddddd'>
        <View>
          <View style={styles.container}>
            <Image
//              source={{uri: venue.images[0].url}}
              style={styles.thumbnail} />
            <View style={styles.rightContainer}>
              <Text style={styles.title}>{venue.name}</Text>
              <Text style={styles.author}>{venue.subtitle}</Text>
            </View>
          </View>
          <View style={styles.separator} />
        </View>
      </TouchableHighlight>
    );
  }
}

module.exports = VenueList;

console.log(venue) produces the following format of data (I am simplifying output here for the purposes of the example):

{
    name: 'Pizza Joint',
        when: [{
            day: ['Sat', 'Sun'],
            start_time: '11:00',
            end_time: '23:00'
        }]
}

I notice the above is not JSON since the quotes on the keys have been stripped out.

like image 548
Michael Mueller Avatar asked Apr 27 '16 21:04

Michael Mueller


People also ask

How do you show array of objects in react native?

To render an array of objects in react with JSX we need to use Array. map() to transform the object into something react can make use of because you cannot directly render an object into React. Instead, by using Array.

How do you access the array of objects in React?

We will use the map function to access each object from the array. The map() method in JavaScript creates an array by calling a specific function on each element present in the parent array. It is a non-mutating method.

How do you display a list of objects in React?

Displaying items from a list of objects in React is very simple. We can iterate over a list of objects using the . map() method in React JSX. Here is the example in which we mapped a list of objects and displayed them in the React app.


1 Answers

Ok I figured it out. The problem was the JSON data set that our API produces has some documents with another definition that delimit the data (e.g. first is document that indicates featured). So React was throwing an error on the first document, which lacked the properties I was attempting to access.

To fix this, I added ternary expressions to the React components to check for the existence of properties:

  renderVenue(venue) {
    console.log(venue);
    return (
      <TouchableHighlight onPress={() => this.showVenueDetail(venue)} underlayColor='#dddddd'>
        <View>
          <View style={styles.container}>
            <Image source={ 'images' in venue ? { uri: 'http://' + venue.images[0].url } : null}       
              style={styles.thumbnail} />
            <View style={styles.rightContainer}>
              <Text style={styles.title}>{venue.name}</Text>
              <Text style={styles.author}>{venue.subtitle}</Text>
              <Text style={styles.author}>{ 'when' in venue ? venue.when[0].start_date : null}</Text>
            </View>
          </View>
          <View style={styles.separator} />
        </View>
      </TouchableHighlight>
    );
  }
}

Perhaps we should modify our API output.

In any event thanks for comments, they were helpful.

like image 60
Michael Mueller Avatar answered Sep 24 '22 12:09

Michael Mueller