[0503] 영화 정렬

한별·2024년 5월 7일

스파르타 내배캠 TIL

목록 보기
14/63

오늘은 영화 검색 팀 프로젝트에서 추가 기능인 영화 정렬을 구현했다.

구현 방법

라디오 버튼을 만들어준다. css는 기존에 존재하던 버튼이랑 똑같은 것을 사용했다.
option 태그는 css가 잘 안 먹어서 열 받는 것 같다..
정렬 기준은 4개로 잡았다.

<div class="sort-container">
  <select id="sort-btn" name="sort">
    <option value="high-rated">평점 높은 순</option>
    <option value="low-rated">평점 낮은 순</option>
    <option value="recent">최신 순</option>
    <option value="old">오래된 순</option>
  </select>
  <img src="./assets/img/sort.png" />
</div>

switch 문과 sort 함수를 이용하여 정렬한 후 css의 order 속성을 이용하여 정렬된 순서로 보이게 하였다!!

export const sortBy = (sortMethod) => {
  const $movieCards = document.querySelectorAll(".card-container");
  let $newMovieCards;

  switch (sortMethod) {
    case "high-rated":
      $newMovieCards = [...$movieCards].sort((a, b) => b.dataset.rate - a.dataset.rate);
      break;
    case "low-rated":
      $newMovieCards = [...$movieCards].sort((a, b) => a.dataset.rate - b.dataset.rate);
      break;
    case "old":
      $newMovieCards = [...$movieCards].sort((a, b) => new Date(a.dataset.release) - new Date(b.dataset.release));
      break;
    case "recent":
      $newMovieCards = [...$movieCards].sort((a, b) => new Date(b.dataset.release) - new Date(a.dataset.release));
      break;
  }
  $newMovieCards.forEach((e, i) => {
    e.style.order = i;
  });
};

그 다음 정렬 select 버튼이 변경될 때마다 정렬 함수를 실행해줬다.

$sortBtn.addEventListener("change", (e) => {
  sortMethod = e.target.value;
  sortBy(sortMethod);
});

트러블 슈팅

언어를 전환할 때, 영화를 api에서 가져온 후에도 설정된 정렬 기준에 맞춰 영화를 보여주고 싶었다.

문제

$langBtn.addEventListener("click", (e) => {
  changeLanguage({ language: e.target.value, page, sortMethod, selectedGenres });
  sortBy(sortMethod);
  prevQuery = "";
});

changeLanguage를 실행한 후 sortBy를 실행하니, 별다른 오류는 없었지만 정렬은 되지 않았다.
api를 비동기 적으로 받아오기 때문에, 영화 카드가 만들어지기 전에 sortBy 함수가 실행되었기 때문이다.

해결

비동기 작업이 완전히 끝난 후에 sort를 진행해주었다.

export const get20Movies = ({ language, page, sortMethod }) => {
  getTopRatedMovies({ language, page }).then((movies) => {
    movies?.forEach((movie) => appendCard(movie, language));
    sortBy(sortMethod);
  });
  $notFound.style.display = "none";
};

+) 이후에는 async, await를 사용해줬다.

export const get20Movies = async ({ language, page, sortMethod, selectedGenres }) => {
  const movies = await getTopRatedMovies({ language, page });
  movies?.forEach((movie) => appendCard(movie, language));
  sortBy(sortMethod);
  showCardsByGenre(selectedGenres);
  $notFound.style.display = "none";
};
profile
글 잘 쓰고 싶어요

0개의 댓글