- TMDB 오픈 API를 이용하여 인기영화 데이터 가져오기
- 영화정보 카드 리스트 UI 구현
개인프로젝트로 인기 영화 리스팅 및 영화 검색 사이트를 제작하고 있다. TMDB의 오픈 API를 이용해 영화 데이터를 가져오고, 이를 이용해 화면에 영화 데이터를 띄워 영화 카드 클릭 시 alert창을 띄우는 것까지 구현해보려고 한다.
영화정보 오픈API인 TMDB(The Movie DB)에서 API문서를 가져온다.
fetch('https://api.themoviedb.org/3/movie/top_rated?language=en-US&page=1', options)
.then(response => response.json())
.then(response => console.log(response))
.catch(err => console.error(err));
이 때 console.log(response)
를 해보면 results에 영화 데이터가 담겨있다는 것을 확인할 수 있다. 이제 여기서 필요한 데이터인 영화 제목(original title), 내용 요약(overview), 포스터 이미지 경로(poster_path), 평점(vote_average), 각 데이터의 id값을 가져오면 된다.
다만 여기서 받아온 데이터는 객체 형태이고, 사용하게 될 results는 여러 객체가 담겨있는 배열인데 이 배열에서 객체와 그 각각의 값에 접근하는 방법이 계속 헷갈렸다.
지금 구현하는 웹사이트에서는 결국 필요 없던 배열이긴하지만, for...of와 함께 쓰면 순환하면서 접근하는 방법을 기억하기 위해 아래 적어본다.
const movie_list_keys_id = []; //값을 담을 빈 배열을 만들어주기
for (let element of data.results) {
//배열을 순회하면서 각 객체 안에 있는 id값 새로운 배열에 넣어주기
movie_list_keys_id.push(element.id)
}
값을 담을 빈 배열을 먼저 만들어주고, data.results 배열의 객체를 인자 element로 받은 뒤, 배열을 순회하면서 id값 객체를 아까 만들어둔 빈 배열에 넣어준다.
이제 화면에 원하는 데이터들을 띄어주기 위해서는 아까 받아온 요청 코드에서 fetch 부분에 코드를 추가해주면 되는데, forEach를 사용해서 data.results
배열을 순회하면서 innerHTML
속성으로 html코드를 추가해줬다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Movie website</title>
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<script type="module" src="script.js"></script>
<header class="header">
<h1>The Best Movie Collections</h1>
<div class="search__box">
<form>
<label for="search" class="search__title">Search Movie : </label>
<input ="text" id="search" placeholder="영화 제목을 검색해보세요" autofocus/>
<button class="search__btn">Search</button>
</form>
</div>
</header>
<main class="main">
<div class="movies" id="movies">
</div>
</main>
</body>
</html>
let movie_list;
fetch('https://api.themoviedb.org/3/movie/top_rated?language=en-US&page=1', options)
.then(response => response.json()) // Promise -> resolve
.then(data => {
movie_list = data;
const movie_list_values = data.results; //영화 정보가 담겨있는 results 값(배열) 가져오기
movie_list_values.forEach(element => {
document.querySelector(".movies").innerHTML += `
<div class="movie__box-wrapper">
<div class="movie__box"token interpolation">${element.id}')" >
<div class="movie__contents" id="${element.id}" token interpolation="('${element.id}')">
<div class="movie__content">
<img class="movie__img" src=${`https://image.tmdb.org/t/p/w400` + element.poster_path} >
<h3 class="movie__title" id="card-title">${element.original_title}</h3>
<p class="movie__sum">${element.overview}</p>
</div>
<div class="rate__box">
<span class="movie__rate">${`Rating : ` + element.vote_average}</span>
</div>
</div>
</div>
</div>
`;
});
})
data.results
배열의 객체를 element 인자로 받아서 ${element.id}
를 비롯한 다른 데이터들을 코드 안에 넣어줬다.
영화카드를 선택하면 해당 아이디값을 띄우는 이벤트를 구현해야했는데, 처음에는 for 문을 활용해서 시도해보려고 했다.
const movieCards = document.querySelectorAll(".movie__box");
function movieCardClick (a) {
alert("영화 id : " + a);
}
for(let i = 0; i < movieCards.length; i++) {
movieCards[i].addEventListener("click", movieCardClick(movieCards[i].id));
}
movieCards배열을 순회하면서 각 객체의 id 값을 alert로 넣어주려고 했는데, 이 부분은 작동하지 않아 다른 방식을 사용했다.
사실 이 방법이 더 간단했는데, fetch에서 html을 넣어줄 때 해당하는 영화 카드 div에 onclick="alert('영화 id : ${element.id}')"
을 넣어주니 별도의 반복문이 없이도 잘 작동하는 것을 확인할 수 있었다.
하지만 아직 반복문이 익숙하지 않아 이후에 연습겸 for문이나 forEach를 통해서 구현하는 것을 다시 시도해보려고 한다.