Film Finder under asynchronous javassript

Please I need help with the FIlm Finder project which falls under Javascript Syntax : request. This is a link to the project : https://www.codecademy.com/journeys/full-stack-engineer/paths/fscj-22-front-end-development/tracks/fscj-22-async-javascript-and-http-requests/modules/wdcp-22-learn-javascript-syntax-requests-b556a0a9-9188-4d31-a713-5c1cbf63bc7c/projects/js-film-finder

The code below is the JS file of the project I worked on. I don’t know why it’s not working because I have done everything right to my knowledge.

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 jsonResponse = await response.json()
      //console.log(jsonResponse)
      const genres = jsonResponse.genres
      //console.log(genres) 
      return genres

    }

  }catch(err){
    console.log(err)
  }

};

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

  }catch(err){
    console.log(err)
  }

};
//getMovies()
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
      return movieInfo



    }

  }catch(err){
    console.log(err)
  }

};

// 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;```

In your getMovies function, the if statement should look like this:

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

Your jsonResponse needs the property .results. This is in step 17. Does this fix your issue?

NO it does not. This is because that’s the same code I have in my getMovies function. Changing it doesn’t change anything

In getMovies,

// You wrote:
const urlToFetch = `${selectedGenre}${discoverMovieEndpoint}${requestParams}`

// Try changing to:
const urlToFetch = `${tmdbBaseUrl}${discoverMovieEndpoint}${requestParams}`;

corrected that but it’s still not working

In getMovieInfo,

// You wrote:
const movieEndpoint = `movie/${movieId}`

// Change to:
const movieEndpoint = "/movie/${movieId}";

no this is wrong because writing template literals uses back ticks instead of double quotes

Took the first one and it worked:

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 jsonResponse = await response.json()
            //console.log(jsonResponse)
            const genres = jsonResponse.genres
            //console.log(genres) 
            return genres

        }

    } catch (err) {
        console.log(err)
    }
};

getGenres().then(json => console.log(json)).catch(err => console.error('error:' + err));

With that in mind, I felt this should probably be generalized. Something like:

const createApiGetService = tmdbKey => {
    const tmdbBaseUrl = 'https://api.themoviedb.org/3';
    return async (endpoint, ...params) => {
        const stub = [`api_key=${tmdbKey}`, ...params].join('&');
        const urlToFetch = `${tmdbBaseUrl}${endpoint}?${stub}`;
        // console.log({urlToFetch});
        const response = await fetch(urlToFetch);
        // console.log({response});
        if (response.ok) {
            const json = await response.json();
            // console.log({json});
            if (response.ok) {
                return json;
            }
        }
        throw response.statusText;
    };
};


const apiGetService = createApiGetService(tmdbKey);

const getGenres = () => apiGetService('/genre/movie/list').then(json => json.genres);

const getMovies = selectedGenre => apiGetService('/discover/movie', `with_genres=${selectedGenre}`).then(json => json.results);

const getMovieInfo = movie => apiGetService(`movie/${movie.id}`, 'language=en-US');

// getGenres().then(json => console.log(json)).catch(err => console.error('error:' + err));
// getMovies(35).then(json => console.log(json)).catch(err => console.error('error:' + err));
// getMovieInfo({ id: 758336 }).then(json => console.log(json)).catch(err => console.error('error:' + err));

While getGenres and getMovies played nice, getMovieInfo barfed on response.json() with error:SyntaxError: Unexpected end of JSON input. This one is kind of out of your hands. The API page seemed fine.

I did this on in a node console; in a browser you could sniff the results better. It’s possible the JSON payload is getting truncated by the fetch. Or, if you’re behind a firewall ( I am ) that middle man might be muddling things.

1 Like

I made a typo and used double quotes instead of backticks. But based on the string you have assigned to tmbdbBaseUrl, you need a forward slash for movieEndpoint

// You wrote:
const movieEndpoint = `movie/${movieId}`

// Change to:
const movieEndpoint = `/movie/${movieId}`;

Thank You Very Much. It’s working now

1 Like