Film Finder error

I was working through the project, and it keeps saying that a certain function is not being found

// Gets a list of movies and ultimately displays the info of a random movie from the list
const showRandomMovie = async() => {
  const movieInfo = document.getElementById('movieInfo');
  if (movieInfo.childNodes.length > 0) {
    clearCurrentMovie();
  };
  const movies = await getMovies();
  const randomMovie = getRandomMovie(movies);
  const info = await getMovieInfo(randomMovie);
  displayMovie(info);
};

The code in question in the function is:

const randomMovie = getRandomMovie(movies);

Whenever I create the const randomMovie variable, it is saying that the getRandomMovie does not exist. It is not seeing that specific function from the helper.js.

I have tried to search the forum, but I am unable to find this exact issue.

Any help would be appreciated. Thanks!

do you have the below function in helpers.js? It’s on line 74

// Returns a random movie from the first page of movies
const getRandomMovie = (movies) => {
const randomIndex = Math.floor(Math.random() * movies.length);
const randomMovie = movies[randomIndex];
return randomMovie;
};

I do have the function. I also noticed it is not seeing:

const selectedGenre = getSelectedGenre();

It is in the getMovie async function and it is not seeing that function in the helper.js, which is in line 14 of helper.js

Can you share the code in your index.html file?

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Film Finder</title>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=M+PLUS+Rounded+1c:wght@400&family=Fredoka+One&family=Questrial&family=Staatliches&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="public/style.css">
    <script defer src="https://kit.fontawesome.com/e918d10e90.js" crossorigin="anonymous"></script>
    <script defer src="public/helpers.js"></script>
    <script defer src="public/script.js"></script>
  </head>
  <body>
    <header>
      <h1 id="appTitle">🍿Film Finder🍿</h1>
    </header>
    <form id="genreForm">
      <label>Choose a genre:</label>
      <select name="genres" id="genres">
      </select>
    </form>
    <button id="playBtn">Let's Play!</button>
    <div id="movieInfo">
      <div id="moviePoster"></div>
      <div id="movieText"></div>
    </div>
    <div id="likeOrDislikeBtns" hidden>
      <button id="likeBtn"><i class="fa-solid fa-thumbs-up"></i></button>
      <button id="dislikeBtn"><i class="fa-solid fa-thumbs-down"></i></button>
    </div>
  </body>
</html>

Here is the index.html. It is the default code and I have not touched it at all. The instructions mostly is just working in the script.js file.

Is the file helper.js or helpers.js?

In your earlier posts, you mentioned helper.js, whereas in index.html of your last post, it is helpers.js

That was a mistype on my part. The name of the file is helpers.js.

Can you post all of your script.js code? Perhaps, it may reveal some clues.

Also, can you copy-paste the exact error message you are seeing?

Here is the index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Film Finder</title>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=M+PLUS+Rounded+1c:wght@400&family=Fredoka+One&family=Questrial&family=Staatliches&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="public/style.css">
    <script defer src="https://kit.fontawesome.com/e918d10e90.js" crossorigin="anonymous"></script>
    <script defer src="public/helpers.js"></script>
    <script defer src="public/script.js"></script>
  </head>
  <body>
    <header>
      <h1 id="appTitle">🍿Film Finder🍿</h1>
    </header>
    <form id="genreForm">
      <label>Choose a genre:</label>
      <select name="genres" id="genres">
      </select>
    </form>
    <button id="playBtn">Let's Play!</button>
    <div id="movieInfo">
      <div id="moviePoster"></div>
      <div id="movieText"></div>
    </div>
    <div id="likeOrDislikeBtns" hidden>
      <button id="likeBtn"><i class="fa-solid fa-thumbs-up"></i></button>
      <button id="dislikeBtn"><i class="fa-solid fa-thumbs-down"></i></button>
    </div>
  </body>
</html>

Here is the helpers.js

// Populate dropdown menu with all the available genres
const populateGenreDropdown = (genres) => {
    const select = document.getElementById('genres')

    for (const genre of genres) {
        let option = document.createElement("option");
        option.value = genre.id;
        option.text = genre.name;
        select.appendChild(option);
    }
};

// Returns the current genre selection from the dropdown menu
const getSelectedGenre = () => {
    const selectedGenre = document.getElementById('genres').value;
    return selectedGenre;
};

// Displays the like and dislike buttons on the page
const showBtns = () => {
    const btnDiv = document.getElementById('likeOrDislikeBtns');
    btnDiv.removeAttribute('hidden');
};

// Clear the current movie from the screen
const clearCurrentMovie = () => {
    const moviePosterDiv = document.getElementById('moviePoster');
    const movieTextDiv = document.getElementById('movieText');
    moviePosterDiv.innerHTML = '';
    movieTextDiv.innerHTML = '';
}

// After liking a movie, clears the current movie from the screen and gets another random movie
const likeMovie = () => {
    clearCurrentMovie();
    showRandomMovie();
};

// After disliking a movie, clears the current movie from the screen and gets another random movie
const dislikeMovie = () => {
    clearCurrentMovie();
    showRandomMovie();
};

// Create HTML for movie poster
const createMoviePoster = (posterPath) => {
    const moviePosterUrl = `https://image.tmdb.org/t/p/original/${posterPath}`;

    const posterImg = document.createElement('img');
    posterImg.setAttribute('src', moviePosterUrl);
    posterImg.setAttribute('id', 'moviePoster');
  
    return posterImg;
};

// Create HTML for movie title
const createMovieTitle = (title) => {
    const titleHeader = document.createElement('h1');
    titleHeader.setAttribute('id', 'movieTitle');
    titleHeader.innerHTML = title;
  
    return titleHeader;
};

// Create HTML for movie overview
const createMovieOverview = (overview) => {
    const overviewParagraph = document.createElement('p');
    overviewParagraph.setAttribute('id', 'movieOverview');
    overviewParagraph.innerHTML = overview;
  
    return overviewParagraph;
};

// Returns a random movie from the first page of movies
const getRandomMovie = (movies) => {
    const randomIndex = Math.floor(Math.random() * movies.length);
    const randomMovie = movies[randomIndex];
    return randomMovie;
};

// Uses the DOM to create HTML to display the movie
const displayMovie = (movieInfo) => {
    const moviePosterDiv = document.getElementById('moviePoster');
    const movieTextDiv = document.getElementById('movieText');
    const likeBtn = document.getElementById('likeBtn');
    const dislikeBtn = document.getElementById('dislikeBtn');
  
    // Create HTML content containing movie info
    const moviePoster = createMoviePoster(movieInfo.poster_path);
    const titleHeader = createMovieTitle(movieInfo.title);
    const overviewText = createMovieOverview(movieInfo.overview);
  
    // Append title, poster, and overview to page
    moviePosterDiv.appendChild(moviePoster);
    movieTextDiv.appendChild(titleHeader);
    movieTextDiv.appendChild(overviewText);
  
    showBtns();
    likeBtn.onclick = likeMovie;
    dislikeBtn.onclick = dislikeMovie;
};

Here is the script.js, the file that the whole project works in. I took out the API key, but I do have one in there.

const tmdbKey = '';
const tmdbBaseUrl = 'https://api.themoviedb.org/3';
const playBtn = document.getElementById('playBtn');

const getGenres = async () => {
  const genreRequestEndpoint = '/genre/movie/list';
  const requestParams = `?api_key=${tmdbKey}`;
  const urlToFetch = `${tmdbBaseUrl}${genreRequestEndpoint}${requestParams}`;
  try {
    const response = await fetch(urlToFetch);
    if(response.ok){
      const jsonReponse = await response.json();
      const genre = jsonReponse.genres;
      return genre;
    }
  } catch(error) {
    console.log(error);
  }
};

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);
  }
};

const getMovieInfo = async(movie) => {
  const movieID = movie.id;
  const movieEndpoint = '/movie/movieID';
  const requestParams = `?api_key=${tmdbKey}`;
  const urlToFetch = `${tmdbBaseUrl}${movieEndpoint}${requestParams}`;
  
  try {
    const response = await fetch(urlToFetch);
    if(response.ok){
      const jsonResponse = await response.json();
      const movieInfo = jsonResponse.results;
      return movieInfo;
    }
  } catch(error) {
    console.log(error);
  }
};

// Gets a list of movies and ultimately displays the info of a random movie from the list
const showRandomMovie = async () => {
  const movieInfo = document.getElementById('movieInfo');
  if (movieInfo.childNodes.length > 0) {
    clearCurrentMovie();
  };
  const movies = await getMovies();
  const randomMovie = getRandomMovie(movies);
  const info = await getMovieInfo(randomMovie);
  displayMovie(info);
};

getGenres().then(populateGenreDropdown);
playBtn.onclick = showRandomMovie;

The file structure is:
files
|\public
||\helpers.js
|| \script.js
||\style.css
|\index.html

The helpers.js, script.js, and style.css are all in the public folder. The public folder and the index.html are in the files folder.

Try the following three changes in script.js.

  • One
// You wrote in getMovies:
const requestParams = `?api_key=${tmdbKey}&?with_genres=${selectedGenre}`;

// Change to:
const requestParams = `?api_key=${tmdbKey}&with_genres=${selectedGenre}`;
  • Two
// You wrote in getMovieInfo:
const movieEndpoint = '/movie/movieID';

// Change to:
const movieEndpoint = `/movie/${movieID}`;
  • Three
// You wrote in getMovieInfo:
const jsonResponse = await response.json();
const movieInfo = jsonResponse.results;
return movieInfo;

// Change to:
const movieInfo = await response.json();
return movieInfo;

What error(s) do you see now?

Are you still getting the same error of the functions not being seen from helpers.js?

Are you working in the Codecademy environment or offsite?

1 Like

That worked!

Thank you so much. The first 2 fixes were I see were errors on my part.

I am sort of confused on why the last fix is written the way it is. I guess I assumed it had to be written the same was as in the getMovies function, but I guess adding that line does not make it work.

Thank you again!

1 Like

The TMDB API has response examples for different queries. You can click the “200 - Result” in the Response section to see example responses.

{
   "page": ...,
    "results": [ {...}, {...}, ... ],
    "total_pages": ...,
    "total_results": ...
}

therefore

const jsonResponse = await response.json();
const movies = jsonResponse.results;
return movies;

allows you to access the correct property.

{
    "adult": ...,
    "backdrop_path": ...,
    "belongs_to_collection": ..., 
    "genres": [ ... ],
    ...,
    ...,
    "title": ...,
    "video": ...,
    "vote_average": ...,
    "vote_count": ... 
}

In this response object, there is no results property. Therefore, jsonResponse.results is trying to access a non-existent property. Instead, it should be:

const movieInfo = await response.json();
return movieInfo;



Also, in getGenres in your script.js file, you have a typo. But, since you make the typo twice so it doesn’t end up causing a problem,

// You wrote:
const jsonReponse = await response.json();
const genre = jsonReponse.genres;

// It should be:
const jsonResponse = await response.json();
const genre = jsonResponse.genres;
1 Like