Not sure what the problem is The code work fine until I try and use the filteredMovies in the displayMovies function not sure what is going on here. I am new to coding and am trying to get the api to work. Everything looks good until I get to this point. Not sure if there is another way to go about doing this or what I have to do to fix this but this has been very furstrating.
const url = 'https://yts.mx/api/v2/list_movies.json?sort_by=download_count&limit=25'; let ytxMovies = []; const movies = 'movies'; searchBar.addEventListener('keyup', (e) => { const searchString = e.target.value; const filteredMovies = ytxMovies.data.movies.filter((list_movies) => { return list_movies.title_english.includes(searchString); }); console.log(filteredMovies); displayMovies(filteredMovies) says movies on line 27 is undifined }); const loadMovies = async () => { try { const res = await fetch(url); ytxMovies = await res.json(); displayMovies(ytxMovies); // console.log(ytxMovies); } catch (err) { console.log(err); } }; const displayMovies = (movie_list) => { // this is the only way to display all the movies const htlmString = movie_list.data.movies .map((movie_list) => { return ` <li class="movie_list"> <h2>${movie_list.title} <p>${movie_list.description_full} <img src="${movie_list.medium_cover_image}"></img> </li> `; }) .join(''); movieList.innerHTML = htlmString; }; loadMovies();
Advertisement
Answer
You’re filtering the ytxMovies.data.movies
in the filteredMovies
so the displayMovies
will get ytxMovies.data.movies
when you pass it so, it doesn’t have the data.movies
when you map
it!
Solution:
Change loadMovies
to this:
const loadMovies = async () => { try { const res = await fetch(url) ytxMovies = await res.json() displayMovies(ytxMovies.data.movies) } catch (err) { console.log(err) } }
This way it will pass an array to the displayMovies
, then change the displayMovies
to:
const displayMovies = (movie_list) => { // this is the only way to display all the movies const htlmString = movie_list .map((movie) => { return ` <li class="movie"> <h2>${movie.title} <p>${movie.description_full} <img src="${movie.medium_cover_image}"></img> </li> ` }) .join('') movieList.innerHTML = htlmString }
I changed your map
a bit in displayMovies
, the whole code:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>Document</title> </head> <body> <input id="search-bar" type="search" /> <ul id="movie-list"> Loading </ul> <script> let searchBar = document.getElementById('search-bar') let movieList = document.getElementById('movie-list') const url = 'https://yts.mx/api/v2/list_movies.json?sort_by=download_count&limit=25' let ytxMovies = [] const movies = 'movies' searchBar.addEventListener('keyup', (e) => { const searchString = e.target.value const filteredMovies = ytxMovies.data.movies.filter((movie) => movie.title_english.includes(searchString) ) displayMovies(filteredMovies) // says movies on line 27 is undifined }) const loadMovies = async () => { try { const res = await fetch(url) ytxMovies = await res.json() displayMovies(ytxMovies.data.movies) } catch (err) { console.log(err) } } const displayMovies = (movie_list) => { // this is the only way to display all the movies const htlmString = movie_list .map((movie) => { return ` <li class="movie"> <h2>${movie.title} <p>${movie.description_full} <img src="${movie.medium_cover_image}"></img> </li> ` }) .join('') movieList.innerHTML = htlmString } loadMovies() </script> </body> </html>