Tony S
Tony S

Reputation: 571

React-native .map undefined is not an object

here my code :

componentDidMount() {
        console.log(this.props.navigation.state.params.idFilm)
        getFilmDetailFromApi(this.props.navigation.state.params.idFilm).then(data => {
            this.setState({
                film: data,
                isLoading: false,
            })
        })
    }

_displayFilm() {
        if(this.state != '') {
            const { film } = this.state
            return (
                <ScrollView>
                    <Image>

                    </Image>
                    <View style={styles.overview_container}>
                        <Text style={styles.overview_title}>{film.title}</Text>
                        <Text style={styles.overview_description}>{film.overview}</Text>
                    </View>
                    <View style={styles.informations_container}>
                        <Text>Sorti le {film.release_date}</Text>
                        <Text>Note : {film.vote_average}</Text>
                        <Text>Nombre de votes : {film.vote_count}</Text>
                        <Text>Budget : {numeral(film.budget).format('0,0[.]00 $')}</Text>
                        <Text>Genre(s) : {film.genres.map((item) => {
                            console.log(item)
                        })}</Text>
                        <Text></Text>
                    </View>
                </ScrollView>
            )
        }
    }

Console.log of film.genres :

Array [
  Object {
    "id": 12,
    "name": "Aventure",
  },
  Object {
    "id": 14,
    "name": "Fantastique",
  },
  Object {
    "id": 10751,
    "name": "Familial",
  },
]

I have this error :

undefined is not an object (evaluating 'film.genres.map')

All is okay but not the Genre(s), anyone have an idea of why the .map don't works correctly with my array of objects ? Thank's.

Upvotes: 0

Views: 3645

Answers (2)

lndgalante
lndgalante

Reputation: 420

I'm going over steps:

1.First, add an initial state value inside your class component

  state = {
    film: null,
    isLoading: false,
  };

2.Second you can trigger the isLoading boolean to true inside your componentDidMount before doing the API call

  componentDidMount() {
    const { navigation } = this.props;
    this.setState({ isLoading: true });

    getFilmDetailFromApi(navigation.state.params.idFilm).then((data) => {
      this.setState({ film: data, isLoading: false });
    });
  }

3.Now we can use this isLoading prop to render a spinner or any loading UI before rendering the films since they're not yet available to access.

_displayFilm() {
    const { film, isLoading } = this.state;

    if (isLoading) {
      return <View>Loading films...</View>;
    }

    return (
      <ScrollView>
        <Image></Image>
        <View style={styles.overview_container}>
          <Text style={styles.overview_title}>{film.title}</Text>
          <Text style={styles.overview_description}>{film.overview}</Text>
        </View>
        <View style={styles.informations_container}>
          <Text>Sorti le {film.release_date}</Text>
          <Text>Note : {film.vote_average}</Text>
          <Text>Nombre de votes : {film.vote_count}</Text>
          <Text>Budget : {numeral(film.budget).format('0,0[.]00 $')}</Text>
          <Text>
            Genre(s) :{' '}
            {film.genres.map((item) => {
              console.log(item);
            })}
          </Text>
          <Text></Text>
        </View>
      </ScrollView>
    );
  }

Hope that works. Let me know if you got any questions!

Upvotes: 1

Shing Ho Tan
Shing Ho Tan

Reputation: 951

please try

...
<Text>Genre(s) : {(film && film.genres) && film.genres.map((item) => {
   console.log(item)
})}</Text>
...

or

...
<Text>Genre(s) : {(film && film.genres) ? film.genres.map((item) => {
   console.log(item)
}) : null}</Text>
...

Upvotes: 1

Related Questions