2

I'm doing a little project using the movie DB API is ReactJs, and I have problems to use async functions, i'm making the api calls in many parts of projects an worked in all of them, but now it's not working.

My axios config:

export default axios.create({
  baseURL: 'https://api.themoviedb.org/3/',
  params: {
    api_key: process.env.REACT_APP_API,
  },
});

In my container I have this

const { setMenuSelected } = useContext(MovieContext);
const [movie, setMovie] = useState({})
const [recommendations, setRecommendations] = useState([]);
const [isLoading, setIsLoading] = useState(true)

useEffect(() => {
  animateScroll.scrollToTop({ smooth: true });
  setMenuSelected('');
  getMovieRecommendations(setRecommendations, match.params.id, setIsLoading);
  setMovie(getMovieDetails(match.params.id, setMovie));
}, [match.params.id, recommendations, isLoading]);

I'm fetching the data in other file just to organize the project

export const getMovieRecommendations = async (
  setRecommendations,
  movieId,
  setIsLoading) => {
  const res = await api.get(`/movie/${movieId}/recommendations`);
  setRecommendations(res.results);
  setIsLoading(false);
}

And to render the movie list I'm passing the recommendations to my component that only use map to render each movie,

<MovieList header={'Recommentadion'} movieList={recommendations} />

But the app allways crash saying "Cannot read property 'map' of undefined", i looked in the network properties in the chrome and my request is finishing with no erros.

Update:

return of console.log(JSON.stringify(res)) I removed the results itens so it wouldn't get too big

{
  "data":{
    "page":1,
    "results":[
      {},
      {},
      {},
      {},
      {},
      {},
      {},
      {},
      {},
      {},
      {},
      {},
      {},
      {},
      {},
      {},
      {},
      {},
      {},
      {}
    ],
    "total_pages":2,
    "total_results":40
  },
  "status":200,
  "statusText":"",
  "headers":{
    "cache-control":"public, max-age=14400",
    "content-type":"application/json;charset=utf-8",
    "etag":"W/\"56ca661f28e43dc3dd2ce41816b517c5\""
  },
  "config":{
    "transformRequest":{

    },
    "transformResponse":{

    },
    "timeout":0,
    "xsrfCookieName":"XSRF-TOKEN",
    "xsrfHeaderName":"X-XSRF-TOKEN",
    "maxContentLength":-1,
    "headers":{
      "Accept":"application/json, text/plain, */*"
    },
    "method":"get",
    "baseURL":"https://api.themoviedb.org/3/",
    "params":{
      "api_key":"fe5b485ed12153ca357c3275cfad6c5c"
    },
    "url":"https://api.themoviedb.org/3/movie/399121/recommendations"
  },
  "request":{

  }
}
4
  • can you show us your MovieList component as well? Commented Mar 1, 2020 at 17:01
  • 2
    This is related to axios actually. You have to fetch res.data.results rather than res.results. Debug and see if you are really getting that property or not. And try checking for res.data rather than res.results. Commented Mar 1, 2020 at 17:05
  • Have you missed this await api.get? I guess you mean await axios.get(..) Commented Mar 1, 2020 at 17:09
  • @DhavalChheda this really works, thanks. Commented Mar 1, 2020 at 17:42

3 Answers 3

1

Try doing:

const res = await api.get(`/movie/${movieId}/recommendations`);
console.log(JSON.stringify(res));

This will print the whole JSON object into a string in the console. Since you're getting undefined and no error, you are most likely accessing the JSON object incorrectly. By printing out the contents this will show you what your JSON object looks like so you can get to the 'results' property successfully.

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

1 Comment

Can you update the question with the returned JSON? I suspect you're just accessing the '.results' property incorrectly.
1

Explain axios.create & Example

axios.create is for initial.. (config)

const axios = Axios.create({ withCredentials: false/true });

Now, create a function using axios like that:

function get(...args) {
  return axios.get(...args)
}

and call as you write:

const res = await get(`/movie/${movieId}/recommendations`);

Comments

0

I think this help you. you should export your axios config like this:

const APIClient = axios.create({
  baseURL: 'https://api.themoviedb.org/3/',
  params: {
    api_key: process.env.REACT_APP_API,
  }
});

export default APIClient;

and then import it to fetch data in another file:

import  APIClient  from "YOUR AXIOS CONFIG FILE";

  export const getMovieRecommendations = async (movieId) => {
  const { data } = await APIClient.get(`/movie/${movieId}/recommendations`);
  return data;
}

In your container set this:

const { setMenuSelected } = useContext(MovieContext);
const [movie, setMovie] = useState({})
const [recommendations, setRecommendations] = useState([]);
const [isLoading, setIsLoading] = useState(true)

const getList=async(movieId)=>{
const res = await getMovieRecommendations(movieId);
  setRecommendations(res.results);
  setIsLoading(false);
}

useEffect(() => {
  animateScroll.scrollToTop({ smooth: true });
  setMenuSelected('');
  getList(match.params.id);
  setMovie(getMovieDetails(match.params.id, setMovie));
}, [match.params.id, recommendations, isLoading]);

3 Comments

I thinks that i'll do this, this way I don't need to pass functions to others.
are you sure that "results" is in your returned data from api?
consider that axios always return a "data" param.

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.