Film Finder, Last Challenge

Hello.

I’ve finished the “Film Finder” project. I’d like to tackle the third challenge, but I’m in need of a hint.

The challenge reads,

“Our API call inside of getMovies() returns many pages of results, but currently our program only randomizes results from the first page. To randomize our results even more, update getMovies() so that movies contains results from a random page instead of the first page.”

Here is the code from the relevant function:

const getMovies = async () => {
  const selectedGenre = getSelectedGenre();
  const discoverMovieEndpoint = 'discover/movie';
  const requestParams = `?api_key=${tmdbKey}&with_genres=${selectedGenre}`;
  const urlToFetch = tmdbBaseUrl+discoverMovieEndpoint+requestParams;
  
  try {
    const response = await fetch(urlToFetch);
    if (response.ok) {
      const jsonResponse = await response.json();
      const movies = jsonResponse.results;
      return movies;
    }
  } catch(error) {
    console.log(error);
  }
};

When I console.log(jsonResponse), I get this:

1. Object

  1. page: 1
  2. results: (20) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
  3. total_pages: 1667
  4. total_results: 33328

So I can see that 1667 pages have returned. But this result is only showing the first. So it seems to have already been filtered down to a single page at this point.

So I take one step back and console.log(response) from the previous line. Now I can no longer see the page or the total_pages. So I’m not sure what else I might be able to try from here.

Thanks in advance for any insight!

I think you can specify the page you want to retrieve using another query parameter:
&page=1 would do the first page.

Also, that jsonResponse object had a property that was the number of pages, so you could do something like

const totalPages = jsonResponse.total_pages;
1 Like

Awesome. That worked well. Thank you.

I suppose that my previous mental block was because I was assuming there’d be a way to randomize the page after obtaining the ‘response’ variable.

So I’ve got it working now. But my current method requires fetching twice. I do it once in order to see how many pages are included in the chosen genre. Then I fetch again after choosing a random number out of that many pages. This seems inefficient, and my hunch is that there might still be a way to achieve this with only one API call.

Does anybody know of a better way?

Here’s my current getMovies function:

const getMovies = async () => {
  const selectedGenre = getSelectedGenre();
  const discoverMovieEndpoint = 'discover/movie';
  const requestParams = `?api_key=${tmdbKey}&with_genres=${selectedGenre}`;
  let urlToFetch = tmdbBaseUrl+discoverMovieEndpoint+requestParams;
  
  try {
    let response = await fetch(urlToFetch);
    if (response.ok) {
      let jsonResponse = await response.json();
      const total_pages = jsonResponse.total_pages;
      const rand_page = Math.floor(Math.random() * total_pages);
      const page_param = `&page=${rand_page}`;
      urlToFetch = tmdbBaseUrl+discoverMovieEndpoint+requestParams+page_param;

      // Second fetch, after obtaining number of pages.
      response = await fetch(urlToFetch);
      if (response.ok) {
        jsonResponse = await response.json();
        const movies = jsonResponse.results;
        return movies;
      }
    }
  } catch(error) {
    console.log(error);
  }
};
1 Like

There’s no page 0, its page 1 thru page total_pages,
so you may want Math.ceil instead

const rand_page = Math.ceil(Math.random() * total_pages);
1 Like

Right! That makes sense.

Any thoughts on whether this can be done with only one API call?