[개인 프로젝트] 영화 검색 사이트 - (1) TMDB 오픈 API 데이터 활용하기

liinyeye·2024년 4월 25일
0

Project

목록 보기
2/44

TIL : Today I Learned

  • TMDB 오픈 API를 이용하여 인기영화 데이터 가져오기
  • 영화정보 카드 리스트 UI 구현

개인프로젝트로 인기 영화 리스팅 및 영화 검색 사이트를 제작하고 있다. TMDB의 오픈 API를 이용해 영화 데이터를 가져오고, 이를 이용해 화면에 영화 데이터를 띄워 영화 카드 클릭 시 alert창을 띄우는 것까지 구현해보려고 한다.

TMDB 오픈 API 이용하여 데이터 가져오기

영화정보 오픈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는 여러 객체가 담겨있는 배열인데 이 배열에서 객체와 그 각각의 값에 접근하는 방법이 계속 헷갈렸다.


  • 객체의 key에만 접근할 때
    -> Object.keys( array ) : 객체의 key 로 이루어진 새 배열이 반환
  • 배열 안에 객체에 접근할 때 -> '.' 또는 '[]'를 이용
  • 배열 안의 각각의 객체와 그 값에 접근할 때 -> arr.object[i].key = value

지금 구현하는 웹사이트에서는 결국 필요 없던 배열이긴하지만, 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값 객체를 아까 만들어둔 빈 배열에 넣어준다.


영화정보 카드 리스트 UI 구현

이제 화면에 원하는 데이터들을 띄어주기 위해서는 아까 받아온 요청 코드에서 fetch 부분에 코드를 추가해주면 되는데, forEach를 사용해서 data.results 배열을 순회하면서 innerHTML 속성으로 html코드를 추가해줬다.

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>

JS

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}를 비롯한 다른 데이터들을 코드 안에 넣어줬다.

영화 카드 클릭 시, 클릭한 영화 id 를 나타내는 alert 창 띄우기

영화카드를 선택하면 해당 아이디값을 띄우는 이벤트를 구현해야했는데, 처음에는 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를 통해서 구현하는 것을 다시 시도해보려고 한다.

profile
웹 프론트엔드 UXUI

0개의 댓글