[24.08.06] 팀프로젝트 6일차

내일은 발표! 오늘 마무리를 하고 발표준비를 하기로 했다.

발표하며 소개할 내용들을 정리하고있는데 담당 튜터님이 오셔서 코드를 보며 개선할 부분을 짚어주셨다.

더보기

1. 테스트용 console.log 지우기

2. config/URL 등 상수들 하나의 파일에 모아 임포트해 사용하기
3. 함수 내부와 함수 호출에서 사용하는 변수명이 다를 경우 의미를 정확하게 할 수 있는 이름이 무엇일지 생각해보기
4. 구조분해할당 사용해서 fetch한 데이터들 더 가독성 좋게 받아보기
5. 댓글 시간 2024-08-06과 같은 양식으로 출력하는 방법 -> toISOString으로 받아 어떻게 그 부분만 받아 사용할 수 있을지 고민해보기 (split, slice 활용)

6. 주석 작성 습관 계속 가져가기 bbb -> 추후 주석을 자동으로 docs로 만들 수 있는 프로그램도 있다

7. 코드를 읽는 방향은 위에서 아래, 왼쪽에서 오른쪽이다. 함수 내에서 사용하는 변수가 아주 위쪽에 선언되어있는 경우가 있는데, 더 자연스럽게 읽을 수 있는 코드를 고민해보기 (현재 조건 확인을 위해 상단에 선언된 변수를 사용했는데, 이런 경우 차라리 조건 자체를 파라미터로 받는 것이 좋음)

 

코드 가독성 피드백 반영

위의 7번은 작성하면서도 이게 맞나.. 했던 부분이라 발표 준비와 특강이 끝나고 바로 반영해보았다!

 

기존 코드

/** 영화 정보 배열을 받아 interestMovies 내부 요소들을 구성한다.
 * @param movieInfoArray - saveMovieInfoArray 혹은 reviewMovieInfoArray
 */
const updateMyMovieSection = (movieInfoArray) => {
  movieInfoArray.forEach((movie) => {
    const tempCard = document.createElement("div");
    tempCard.className = "movie-card";
    tempCard.id = movie.id;

    tempCard.innerHTML = `
    <img src=${movie.posterPath} alt="영화이미지" />
    <div class="text_area">
      <h3>${movie.title}</h3>
      <p>${movie.overview}</p>
    </div>`;

    const tempButton = document.createElement("span");
    tempButton.className = "material-symbols-outlined saveButton";

    if (saveMovieIDArray.includes(String(movie.id))) {
      tempButton.classList.add("saved");
    }

    tempButton.style.fontSize = "36px";
    tempButton.innerText = "favorite";

    tempButton.addEventListener("click", saveButtonEvent);

    tempCard.appendChild(tempButton);
    tempCard.addEventListener("click", moveToDetail);

    const movieSection = movieInfoArray === saveMovieInfoArray ? savedMoviesSection : reviewedMoviesSection;
    movieSection.appendChild(tempCard);
  });
};

 

영화의 정보가 담긴 배열(API에서 fetch해옴)을 파라미터로 받아 영화 카드를 만들어주고, 어떤 배열에 담긴 정보이냐를 판단해 해당하는 DOM 요소에 자식요소로 추가해주는 함수다!

다른 동작은 모두 동일한데 어디에 추가해준냐만 달라 고민을 하다 저렇게 구현했었는데, 조건을 판단하기위해 사용하는 saveMovieInfoArray가 아주 위쪽에 선언되어있어 해당 함수의 스코프를 벗어나 한참 위로 올려야 의도 파악이 가능하므로 좋지 않은 방식 같다는 피드백을 받았다. 대신 이런 경우는 파라미터를 하나 더 사용하더라도 조건을 보내주어 읽기 좋게 만들어주는 것을 추천해주셨다.

 

변경한 코드

다른 분이 주로 작업하시는 리뷰 작성을 구현하는 스크립트에서 true/false로 리뷰를 등록하는 중인지, 삭제하는 중인지 파라미터를 넘겨받는 함수를 구현했었는데 덕분에 빠르게 이해할 수 있었다. 조건을 파라미터로 받은 함수를 더 늦게 작성하긴했지만.. 이 때는 비슷하게 생각해두고 왜 저기선 떠올리지 못했을까...???

/** 영화 정보 배열을 받아 interestMovies 내부 요소들을 구성한다.
 * @param movieInfoArray - saveMovieInfoArray 혹은 reviewMovieInfoArray
 * @param type - "saveMovie" 혹은 "reviewMovie"
 */
const updateMyMovieSection = (movieInfoArray, type) => {
  movieInfoArray.forEach((movie) => {
    const tempCard = document.createElement("div");
    tempCard.className = "movie-card";
    tempCard.id = movie.id;

    tempCard.innerHTML = `
    <img src=${movie.posterPath} alt="영화이미지" />
    <div class="text_area">
      <h3>${movie.title}</h3>
      <p>${movie.overview}</p>
    </div>`;

    const tempButton = document.createElement("span");
    tempButton.className = "material-symbols-outlined saveButton";

    if (saveMovieIDArray.includes(String(movie.id))) {
      tempButton.classList.add("saved");
    }

    tempButton.style.fontSize = "36px";
    tempButton.innerText = "favorite";

    tempButton.addEventListener("click", saveButtonEvent);

    tempCard.appendChild(tempButton);
    tempCard.addEventListener("click", moveToDetail);

    const movieSection = type === "saveMovie" ? savedMoviesSection : reviewedMoviesSection;
    movieSection.appendChild(tempCard);
  });
};

 

확실히 조건을 바로 파악하기 좋은 것 같다. 그런데.. 이렇게하면 아무 문자열이나 들어올 수 있는데 둘 중 하나만 매개변수로 넘기도록 제한할 수 있는 방법은 없을까??

 

변경한 코드 2

let movieSection;

switch (type) {
  case "saveMovie":
    movieSection = savedMoviesSection;
    break;
    
  case "reviewMovie":
    movieSection = reviewedMoviesSection;
    break;
    
  default:
    console.error('잘못된 영역을 입력했습니다. "saveMovie", "reviewMovie" 중 하나를 입력해주세요. 입력: ', type);
    break;
}

movieSection.appendChild(tempCard);

우선 떠오른 방법이 있어 조건을 확인하는 부분을 위와 같이 변경해주었다.

 

updateMyMovieSection(saveMovieInfoArray, "save");

뜬금없이 이상한 곳에 추가되는 것보다 어떤게 잘못된 건지 알려줘야 수정하기 편할 것 같아 두 경우가 아닌 다른 값을 입력한 경우 에러메세지를 띄우게 했다. 얼마전 파이어베이스 오류의 교훈...

 

그런데.. 굳이 실행하고 콘솔까지 안가도 잘못입력한 걸 알려줄 수 있는 방법은 없나..??? 주석으로 둘중 하나를 써달라고 적긴했지만 그냥 썼을 때 바로 알려주면 좋을 것 같은데.. -> 찾아봤는데 undefined 검증 관련만 많이 나와서 내일 튜터님께 다시 여쭤보자

 

 

(08.07)

javascript 에서는 어쩔 수 없고, typescript에서 이 불편함을 해소할 수 있다고 한다!

 

구조분해할당 활용해 깔끔하게 데이터 받기

기존 코드

const createMovieCard = (id, title, posterPath, overview, vote) => {
  // 생략
}

topratedMovie.forEach(function (movie) {
  let img_url = "https://image.tmdb.org/t/p/w500" + movie.poster_path;
  let movie_title = movie.title;
  let overview = movie.overview;
  let vote = movie.vote_average;
  let id = movie.id;
  
  createMovieCard(id, movie_title, img_url, overview, vote);
});

 

변경한 코드

topratedMovie.forEach(function (movie) {
  let [img_url, title, overview, vote, id] = [
    movie.poster_path,
    movie.title,
    movie.overview,
    movie.vote_average,
    movie.id
  ];
  
  createMovieCard(id, title, img_url, overview, vote);
});

 

fetch 받아와서 영화 카드를 요소로 추가하는 부분이 많아서 나름 createMovieCard라는 함수로 만들어봤는데 결국 저 fetch 받아와서 각 데이터를 변수에 담는 부분도 반복된다는 걸 생각하지 못했다 ㅋㅋㅋㅋ 데이터가 다르다는 생각때문에 그랬던 것 같다..

 

변경한 코드 2

const createMovieCard = (movie) => {
  let [posterPath, title, overview, vote, id] = [
    movie.poster_path,
    movie.title,
    movie.overview,
    movie.vote_average,
    movie.id
  ];

  // 생략
}

topratedMovie.forEach(function (movie) {
  createMovieCard(movie);
});

fetch한 데이터 movie 자체를 createMovieCard() 자체로 넘겨서 변수에 할당하는 것까지 함수 내에서 처리해줬다.

훨씬 깔끔해졌다!