[리팩토링 일기] 이상한 나라의 초콜릿 쇼핑몰 리팩토링 - 카테고리 필터링

박소정·2022년 9월 22일
0
post-thumbnail

다음으로 리팩토링을 결심한 부분은 홈 부분과 상품 목록 부분이었다.
내가 구현한 부분은 아니지만 프로젝트를 실행시키면 처음으로 마주하게 되는 부분인데 정적으로 하드코딩해두어서 계속해서 에러가 뜨는 것이 조금 신경쓰여 리팩토링을 결심했다.

우선 아래 부분의 이 상품 어때요? 부분!!
프로젝트 마감 직전에 너무 휑한 느낌이 들어 급하게 추가한 부분이었는데 이 부분이 아무 상품도 뜨지 않고 있었다.

코드를 열어보니 하드코딩 되어진 상품의 id 값으로 목록을 만들어 내고 있었고, mongodb를 프로젝트 계정이 아닌 내 계정을 사용하고 있어서 안뜨는 것이 아주 당연했다ㅋㅋㅋ

async function getProductList() {
  try {
    const productData = await get("/api/products");
    const productList = document.querySelector(".productList");

    productData.forEach((e) => {
      if (e._id === recommend[q]) {
        console.log(e);
        const productItem = document.createElement("div");
        productItem.setAttribute("class", "productItem");
        productItem.classList.add(e.category.name);
        const aTag = document.createElement("a");
        aTag.setAttribute("href", `/detail/${e._id}`);

        const itemImg = document.createElement("img");
        const itemName = document.createElement("div");
        const itemPrice = document.createElement("div");
        itemImg.setAttribute("class", "itemImg");
        itemImg.setAttribute("src", `${e.img}`);
        itemName.setAttribute("class", "itemName");
        itemPrice.setAttribute("class", "itemPrice");

        const nameText = document.createTextNode(`${e.name}`);
        const priceText = document.createTextNode(`${addCommas(e.price)}`);
        itemName.appendChild(nameText);
        itemPrice.appendChild(priceText);

        aTag.appendChild(itemImg);
        aTag.appendChild(itemName);
        aTag.appendChild(itemPrice);
        productItem.appendChild(aTag);
        productList.appendChild(productItem);

        q += 1;
      }
    });
  } catch (err) {
    console.error(err.stack);
    alert(`문제가 발생하였습니다. 확인 후 다시 시도해 주세요: ${err.message}`);
  }
}

const recommend = [
  "62a1a4e722d988ddbbe58d27",
  "62a2cf61ba1727d03dbd61b7",
  "62a2dc9543b7ffa5da32ebf9",
  "62a2de3343b7ffa5da32ec0d",
];
var q = 0;
getProductList();

이렇게 recommend 배열의 값을 만들어 두고 같은 아이디 값의 상품을 보여주는 것 대신에

async function getProductList() {
  try {
    const productData = await get("/api/products");
    const productList = document.querySelector(".productList");

    for (let i = 0; i < 4; i++) {
      const productItem = document.createElement("div");
      productItem.setAttribute("class", "productItem");
      productItem.classList.add(productData[i].category.name);
      const aTag = document.createElement("a");
      aTag.setAttribute("href", `/detail/${productData[i]._id}`);

      const itemImg = document.createElement("img");
      const itemName = document.createElement("div");
      const itemPrice = document.createElement("div");
      itemImg.setAttribute("class", "itemImg");
      itemImg.setAttribute("src", `${productData[i].img}`);
      itemName.setAttribute("class", "itemName");
      itemPrice.setAttribute("class", "itemPrice");

      const nameText = document.createTextNode(`${productData[i].name}`);
      const priceText = document.createTextNode(
        `${addCommas(productData[i].price)}`
      );
      itemName.appendChild(nameText);
      itemPrice.appendChild(priceText);

      aTag.appendChild(itemImg);
      aTag.appendChild(itemName);
      aTag.appendChild(itemPrice);
      productItem.appendChild(aTag);
      productList.appendChild(productItem);
    }
  } catch (err) {
    console.error(err.stack);
    alert(`문제가 발생하였습니다. 확인 후 다시 시도해 주세요: ${err.message}`);
  }
}

getProductList();

4개의 상품으로 제한해두고 반복문을 돌려 화면에 그리는 방식으로 리팩토링 하였다.

다음으로 바꾸어야 할 부분은 카테고리로 필터링 하는 부분!!

이 부분 역시 홈 화면에서는 하드코딩 되어있어 동적으로 바뀌지 않았고, 그래서 필터링 할때 해당 이름을 찾지 못해 에러가 나는 것이었다.
다행히 상품 목록에서는 동적으로 받아오고 있었기 때문에 home 부분만 수정하면 되었다!
근데 그럴리가 없지!!

우선 하드 코딩된 부분을 카테고리 부분의 api를 요청해 받아오게 수정하였다.

async function makeLiFunction() {
  try {
    const categoryData = await get("/api/categories");
    const categoryUl = document.querySelector("#categoryList");

    const allBtnLi = document.createElement("li");
    allBtnLi.textContent = "전체보기";
    allBtnLi.classList.add("allBtn");
    allBtnLi.addEventListener("click", () => {
      window.location.href = "/productlist";
    });
    categoryUl.appendChild(allBtnLi);

    categoryData.forEach((e) => {
      const liForCategory = document.createElement("li");
      liForCategory.textContent = e.name;
      liForCategory.classList.add(e.name);
      liForCategory.addEventListener("click", () => {
        sessionStorage.setItem("category", e.name);
        window.location.href = "/productlist";
      });
      categoryUl.appendChild(liForCategory);
    });
  } catch (err) {
    console.error(err.stack);
    alert(`문제가 발생하였습니다. 확인 후 다시 시도해 주세요: ${err.message}`);
  }
}

동적으로 카테고리 필터링 버튼을 만들어주게 세팅을 완료하였는데 역시나
‼️에러 발생‼️

필터링하는 각각의 버튼을 클릭하면 classList를 받아올 수 없다는 에러가 발생했는데, 상품의 목록을 불러오는 부분의 필터링 함수를 봤더니 class 이름으로 필터링을 하고 있었다
하드 코딩 되어있던 부분에도 class를 추가 하지 않았던데 대체 어떻게 작동 되었었나 봤더니 원래 코드에서도 발생하던 에러였는데 한번 클릭을 하면 이때 class가 부여되기 때문에 다음 클릭부터는 에러가 발생하지 않기 때문에 작동이 되었던 것!!ㅋㅋㅋㅋㅌㅋㅌㅋㅌ 지금 손대는 부분 아니라고 경고창을 너무 사뿐히 무시했던 과거의 나...


    const allBtnLi = document.createElement("li");
    allBtnLi.textContent = "전체보기";
    allBtnLi.classList.add("allBtn");
    allBtnLi.addEventListener("click", () => {
      window.location.href = "/productlist";
      allBtnLi.classList.add("selectCategory");
    });
    categoryUl.appendChild(allBtnLi);

    categoryData.forEach((e) => {
      const liForCategory = document.createElement("li");
      liForCategory.textContent = e.name;
      liForCategory.classList.add(e.name);
      liForCategory.addEventListener("click", () => {
        sessionStorage.setItem("category", e.name);
        liForCategory.classList.add("selectCategory");
        window.location.href = "/productlist";
      });
      categoryUl.appendChild(liForCategory);

그래서 이렇게 home 화면의 카테고리 필터링 단추를 클릭할때에도 class가 부여되도록 수정하였더니 에러없이 잘 작동이 되었다!


다음 리팩토링은 alert모달로 돌아오겠습니다 (_ _)

쇼핑몰 리팩토링 코드보러가기

0개의 댓글