프로젝트의 해설 강의를 시청하고, 코드를 어떤 방식으로 구현해야 하는지 깨닫게 되었다.
그래서 시청 직후, 코드 리팩토링(Code Refactoring)을 실시하였다.
하나의 디렉토리에서 html, css, js 파일을 모두 관리했던 기존 방식에서,
CSS 파일을 관리하는 style 폴더, js 파일을 관리하는 src 폴더를 생성하여 HTML과 분리했다.
기존 | 개선 방식 |
---|---|
index.html | index.html |
main.css | /style/main.css |
main.js | /src/main.js |
JavaScript의 기능 별로 파일을 분리하여 가독성이 편하도록 하였다.
AS-IS | TO-BE |
---|---|
main.js | |
main.js | search.js (검색 기능) |
showMovies.js(영화 출력 기능) |
또한, 모듈(module)을 사용하여 각 기능들을 main.js로 import하여 사용했다.
// search.js
export const showSearchResult = (searchKeyword) => {...};
// main.js
import { generateMovieList } from "./showMovies.js";
import { showSearchResult } from "./search.js";
한 줄에 1개의 영화만 나오던 화면을 grid를 사용하여 한 줄에 여러 개의 영화가 나오도록 설정했다.
#movie-list {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 2rem;
padding: 2rem;
}
async, await 키워드를 사용하여 비동기 함수 형태로 함수를 분리하였다.
// AS-IS
const options = {
method: 'GET',
headers: {
accept: 'application/json',
Authorization: 'Bearer my_api_key'
}
};
fetch(url, options)
.then((res) => res.json())
.then((data) => {
const movie_data = data["results"];
}
// TO-BE
const generateMovieList = async () => {
const movies = await fetchMovieData();
}
async function fetchMovieData() {
const options = {
method: "GET",
headers: {
accept: "application/json",
Authorization:
'Bearer my_api_key'
},
};
const movie_data = await fetch(url, options).then((data) => data.json());
return movie_data.results;
}
기존의 새로운 배열을 출력하는 방식이 아닌, display style을 변경하는 방식으로 개선하였다.
// AS-IS
function showSearchResults() {
fetch(url, options)
.then((res) => res.json())
.then((data) => {
const movie_data = data["results"];
const searched_list = movie_data.filter((movie) => {
return (
movie.title.includes(inputText.value) ||
movie.original_title.toUpperCase().includes(inputText.value.toUpperCase()
);
});
const searched_result = searched_list.map((movie) => {
let movie_html = `
<div class="movie_card"token interpolation">${movie.title}] 의 Movie ID : ${movie.id}')">
<div class="movie_content">
<h2>${movie.title} (${movie.original_title})</h2>
<p><strong>개봉일</strong> : ${movie.release_date} / <strong>평점</strong> : ${movie.vote_average}</p>
<p>${movie.overview}</p>
</div>
<div class="movie_img">
<img src="https://image.tmdb.org/t/p/w185${movie.poster_path}" />
</div>
</div>`;
return movie_html;
});
movie_list.innerHTML = "":
searched_result.forEach((movie) => {
movie_list.innerHTML += movie;
});
})
.catch((err) => console.log(err));
}
// TO-BE
// 검색 결과 출력
const showSearchResult = (searchKeyword) => {
const movieItems = document.querySelectorAll(".movie-item");
movieItems.forEach((item) => {
const title = item.querySelector(".movie-title").textContent; // 한국어 제목
const originalTitle = item.querySelector(".movie-original-title").textContent.toUpperCase(); // 원제
const searchedValue = searchKeyword;
if (title.includes(searchedValue) || originalTitle.includes(searchedValue.toUpperCase())) {
item.style.display = "block";
} else {
item.style.display = "none";
}
});
};
fetch할 URL 입력값을 선택할 수 있게 하여 카테고리를 설정할 수 있게 하였다.
<!-- index.html -->
<ul class="sort-list">
<li id="popular">Popular</li>
<li id="topRated">Top Rated</li>
</ul>
// showMovies.js
const url = `https://api.themoviedb.org/3/movie/${urlInfo}?language=ko-KR`;
const generateMovieList = async (urlInfo) => {
const movies = await fetchMovieData(urlInfo);
}
// main.js
const $popular = document.querySelector("#popular");
const $topRated = document.querySelector("#topRated");
$popular.addEventListener("click", (event) => {
event.preventDefault();
generateMovieList("popular");
});
$topRated.addEventListener("click", (event) => {
event.preventDefault();
generateMovieList("top_rated");
});