0

I have the following component and I'm trying to retrieve a list of movies from an API. However, the variable movies does not contain the expected result.

What am I doing wrong?

Here's the code:

import React, { Component, } from 'react'
import { View } from 'react-native'
import { 
  List, 
  ListItem,
  Text,
} from 'native-base';

class Test extends Component {

  render() {
    var movies = this.getMoviesFromApi();

    for(var movie in movies)
    {
      console.warn(movie);
    }

    return (
          <List dataArray={movies}
            renderRow={(movie) =>
              <ListItem>
                  <Text>{movie}</Text>
              </ListItem>}
          />
      );
  }

  async getMoviesFromApi() {
    try {
      let response = await fetch('https://facebook.github.io/react-native/movies.json');
      let responseJson = await response.json();
      return responseJson.movies;
    } catch(error) {
      console.error(error);
    }
  }
}

export default Test;
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
msimons
  • 495
  • 10
  • 19
  • 1
    `getMoviesFromApi` is an async function, which means it returns a promise. You have to handle the promise properly. – Felix Kling Oct 19 '16 at 20:18
  • 4
    To expand on @FelixKling response, using `var movies = await this.getMoviesFromApi()` would work, however `render` is not an async function, nor is it a good place to fetch stuff from a server since render gets called a trillion times over the course of a React application lifecycle. Consider moving that logic into `componentDidMount` and setting some state once the response has returned. – azium Oct 19 '16 at 20:20
  • Related: [How do I return the response from an asynchronous call?](http://stackoverflow.com/q/14220321/218196) – Felix Kling Oct 19 '16 at 20:22
  • var movies = this.getMoviesFromApi().done(); – msimons Oct 21 '16 at 17:01

1 Answers1

2

In your fetch call, you should return the response with a then() call. Here's an example from an app I wrote:

// inside Utils/api.js
getAllSchools(accessToken){

var url = `${baseUrl}/schools`
return fetch(url).then((res) => res.json())
 .catch((e) => {
  console.log('an error occurred getting schools', e)
  api.logError(e.message);
 })
},

Then, wherever you're calling your function, set movies to that response:

api.getAllSchools("klsafj").then((res) => {
 var movies = res.data
 // then do whatever else you want to do with movies
 // or you could set movies to a state and use elsewhere
})

Hope this helps.

toddmetheny
  • 4,405
  • 1
  • 22
  • 39