1
export default class LaunchingScreen extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      isLoading: true,
      dataSource: null,
      refreshing: false
    };
  }

//When screen is pulled down this calls for fresh through the state its int

  _onRefresh = () => {
    this.setState({ refreshing: true });
    this.componentDidMount().then(() => {
      this.setState({ refreshing: false });
    });
  };
//Gets data from API 
  componentDidMount() {
    return fetch("https://launchlibrary.net/1.4/launch?mode=verbose")
      .then(response => response.json())
      .then(responseJson => {
        this.setState({
          isLoading: false,
          dataSource: responseJson.launches
        }); 
      })
      .catch(error => {
        console.log(error);
      });
  }
//Renders Screen
  render() {
    //Refresh if statement
    if (this.state.isLoading) {
      return (
        <View style={styles.container}>
          <ActivityIndicator />
        </View>
      );
    } else {
        //Launches is what its called on later to display what is being said in launches
        let launches = this.state.dataSource.map((item, key) => {
        return (
          <View key={key} style={styles.container}>
              <View style={styles.subcontainer}>
              <Text>{item.missions[0].name}</Text>
              </View>
          </View>
        );
      });
      //Allows the screen to be scrollable w/ refresh control 
      return (
        <View style={styles.Background}>
          <ScrollView
            contentContainerStyle={styles.contentContainer}
            refreshControl={
              <RefreshControl
                refreshing={this.state.refreshing}
                onRefresh={this._onRefresh}
              />
            }
           >
            {launches}
          </ScrollView>
        </View>
      );
    }
  }
}

Problem I'm having is getting data (the mission name) from the launch library API which is in an array. I fetch the data and put them in item/key. When i call the mission name by item.missions[0].name (missions[0] is the array ) i get a TypeError: undefined is not an object. I've been told i have to check if missions is undefined but don't understand the solution to that.

3 Answers 3

2

You are trying to get to an index (0) of an array assuming you have one and that it actually has values in it.

You could check and make sure like this:

<Text>
  {Array.isArray(item.missions) && item.missions.length && item.missions[0].name}
</Text>

This would check if the value is actually an array with a length bigger than 0 so you can access the 0 index.

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

2 Comments

Thanks you for the explanation! I got it to work with that line!
@NoeDuran I hope, data is always in array, just checking length should work fine.
1

Do this conditional check before accessing array

<Text>{item.missions && item.missions[0].name}</Text>

Comments

1

Try following

<Text>{item?.missions[0]?.name}</Text>

2 Comments

I've never seen that syntax before. What does it do?
it checks item is not null and then get the missions[0] and checks it is not null and then get the name

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.