오늘부터 개인 프로젝트를 시작했다.
주어진 과제는 다음과 같았다.
- 영화 open API를 이용해 영화 데이터를 가져온 후 웹에 구현하기 (영화 이미지, 영화 제목, 내용, 평점)
- 웹에 구현한 내용을 클릭하면 영화 ID가 alert창에 뜨도록 하기
- 영화 검색 기능 구현하기
처음에는 이 기능을 어떻게 구현하면 좋을지를 생각하며 프레임워크를 짜봤고 어떤 기능이 추가적으로 들어가면 좋을지 생각해봤다.
<기능 구상>
우선 가장 기본적인 필수과제부터 넣기로 했다. 기본적인 css는 주어진 예시파일의 css 기본틀을 차용했고 따로 display : grid를 적용해서 웹 구역을 나눠주었다.
또한 추가적으로 들어갈 기능들을 구상해봤는데 로그인 기능 넣기, 로그인에 따른 영화 장바구니 만들기.
각 영화정보 카드에 좋아요 누르면 좋아요한 갯수 표시하기(local storage 사용하면 한 명이 한번씩만 좋아요 누를 수 있게 만들 수 있을 것 같다.)
좋아요가 많이 눌러진 상위 5개 영화에 대해 영화 위에 왕관이 뜨게 하기.
<기능 구현>
프로젝트의 시작으로 데이터를 가져와 웹에 구현하는 것부터 시작했다.
먼저 open API에서 영화 데이터를 가져와야 했다.
fetch 라는 함수로 데이터를 가져왔는데 fetch를 처음 접했기 때문에 데이터가 잘 넘어온건지, 넘어왔다면 어디에 있는지 알 수 없었다.
일단 무작정 console.log를 찍어보며 데이터가 어디있는지 찾았다.
찾다보니 데이터는 response안에 담겨있다는 것을 알게 되었다.
처음 생각으로는 response를 내가 지정한 임의의 변수에 담아 사용할 생각이었다. 하지만 fetch밖으로 response를 꺼내보니 데이터가 전혀 전달되지 않고 있었다.
(나중에 알고 보니 fetch함수의 실행이 끝나면서 그 안의 데이터의 내용도 같이 사라지는 것이었다.
이를 해결하기 위해서는 async, await를 사용해 일정한 변수에 담아 사용하면 된다.)
async function getMovies() {
try {
const response = await fetch('<https://api.themoviedb.org/3/movie/top_rated?language=en-US&page=1>', options);
const data = await response.json();
return data.results;
} catch (err) {
console.error(err);
}
}
getMovies().then(movies => console.log(movies));
async, await로 작업하는 방식은 위와 같이 해주면 된다. 하지만 주어진 과제에서 promise then을 사용하는 예시를 주었기 때문에 그대로 사용했다.
또한 fetch 밖으로 데이터를 꺼내올 수 없었기 때문에 fetch내에서 작업을 해주는 식으로 진행했다
데이터를 가져오는 것까지 성공했기 때문에 이제 데이터를 웹에 구현해주어야 했다.
그 방법으로
- 데이터를 넣을 div박스를 미리 만들어 둔 뒤에 데이터 집어넣기
- div박스를 js로 생성하며 동시에 데이터 넣기
를 생각해보았다.
두 방법 모두 연습해보자는 생각으로 div박스부터 만들어서 데이터를 넣었다.
querySelector로 div 하나에 넣는 연습부터 querySelectorAll으로 div 여러개에 동시에 넣는 연습도 했다.
하지만 역시나 1번의 방법은 div박스를 일일히 생성해야 한다는 하드코딩적인 요소가 많았고 프로젝트는 2번으로 진행하기로 했다.
div 박스를 js로 생성하여 넣는 방법에서는 data내에 results가 들어있고 그 안에 각각의 영화내용 전부가 들어가 있기 때문에 results를 forEach로 각각 영화의 제목, 내용, 평점 등을 가져온 후에 inner html을 이용해 각 카드에 넣어주었다.
동시에 카드를 만들면서 카드를 클릭할때마다 id가 alert에 나오도록 eventListener를 붙여주었다.
// 카드 안에 데이터 넣기
fetch(
"https://api.themoviedb.org/3/movie/top_rated?language=en-US&page=1",
options
)
.then((response) => response.json())
.then((data) => {
const $movieCardList = document.querySelector(".cardContainer");
// movieCard 생성 및 데이터 넣기
data.results.forEach((movie) => {
const $movieCard = document.createElement("div");
$movieCard.className = "movieCard";
$movieCard.innerHTML = `
<img src="https://image.tmdb.org/t/p/w500${movie.poster_path}" alt="${movie.title}">
<h3>${movie.title}</h3>
<p>${movie.overview}</p>
<p>rating : ${movie.vote_average}</p>`;
$movieCardList.appendChild($movieCard);
// 카드 클릭시 alert 띄우기
$movieCard.addEventListener('click', printID);
function printID() {
alert(`영화 id: ${movie.id}`);
};
})
})
.catch((err) => console.error(err));
# querySelector와 querySelectorAll 의 차이
querySelectorAll 은 셀렉터 그룹에 일치하는 document element list를 반환한다. 따라서 forEach, map 등을 이용하여 각각의 querySelector에 addEventListener을 달아주어야 한다.
(querySelecotr로는 eventListener가 '하나'만 적용되기 때문에 querySelectorAll을 사용해주어야 한다.)
'TIL' 카테고리의 다른 글
2023_10_20 TIL (0) | 2023.10.23 |
---|---|
2023_10_19 TIL (1) | 2023.10.23 |
2023_10_17 TIL (0) | 2023.10.19 |
2023_10_16 TIL (2) | 2023.10.18 |
2023_10_13 TIL (1) | 2023.10.15 |