2025년 1월 16일

김동환·2025년 1월 16일

오늘의 코드

📚 오늘 배운 것: 주소 등록 기능 구현(TIL)


1. HTML 구조

createAddress.html은 주소 등록 화면을 제공하며, 아래의 주요 요소로 구성되어 있습니다:

  • form: 사용자가 주소 이름과 주소를 입력할 수 있는 입력 필드.
  • labelinput: 사용자가 필수 정보를 입력하도록 설계.
  • button: 폼 제출 버튼.
  • script: 자바스크립트 파일인 createAddress.jsdefer 속성을 사용해 로드.

2. JavaScript 기능

createAddress.js는 주소 등록을 처리하는 로직을 포함하고 있습니다. 주요 기능은 다음과 같습니다.


3. 주요 로직 설명

  1. 폼 제출 이벤트 리스너 추가

    • document.querySelector를 사용해 폼 요소를 선택하고, addEventListenersubmit 이벤트를 감지.
    • preventDefault()를 호출해 기본 제출 동작 방지.
  2. 입력 값 검증

    • addressNameaddress 필드를 확인하고 비어 있으면 경고 메시지를 출력.
  3. 주소 개수 제한

    • 사용자가 최대 5개의 주소를 등록할 수 있도록 제한.
    • fetch를 통해 GET 요청으로 사용자의 기존 주소 목록을 가져옴.
    • 주소가 5개 이상일 경우 경고 메시지를 출력하고 등록을 차단.
  4. 주소 등록 요청

    • POST 요청을 통해 입력받은 addressNameaddress를 서버로 전송.
    • 성공하면 "주소가 등록되었습니다." 메시지를 출력하고 조회 페이지로 이동.
    • 실패하면 오류 메시지를 출력.
  5. 예외 처리

    • try-catch 블록을 사용해 비동기 요청에서 발생하는 오류를 처리.
    • 오류 메시지를 사용자에게 경고창으로 전달.

4. 사용된 HTTP API

  • GET: api/users/me/addresses
    • 현재 사용자의 주소 목록을 확인.
    • 최대 5개의 주소 제한을 위한 검증.
  • POST: api/users/me/addresses
    • 새 주소를 등록.

5. 오늘의 깨달음

  • 폼 이벤트 처리: preventDefault()를 사용해 기본 동작을 제어하는 중요성을 다시 느꼈다.
  • 입력 검증: 클라이언트 측에서 데이터를 검증하는 것이 UX와 서버 부하 감소에 얼마나 중요한지 이해했다.
  • 비동기 요청: fetch API와 async/await를 사용한 깔끔한 비동기 처리가 유용했다.
  • 에러 처리: 사용자 친화적인 에러 메시지가 사용자 경험을 크게 향상시킬 수 있다는 점을 깨달았다.

6. 개선할 점

  • UI 향상: 입력값 검증 실패 시, 단순한 경고창 대신 필드 옆에 오류 메시지를 표시하도록 개선할 수 있다.
  • 로딩 상태 표시: 네트워크 요청 중에 로딩 스피너를 추가해 사용자 피드백을 제공할 수 있다.
  • 코드 재사용성: GET/POST 요청을 처리하는 함수를 별도로 분리해 코드 중복을 줄일 수 있다.

7. 향후 학습 목표

  • 주소 등록 시 Google Maps API를 사용해 유효한 주소인지 확인.
  • 테스트 코드를 작성해 이 기능이 잘 동작하는지 확인하기.

오늘은 주소 등록 기능을 구현하며 사용자 입력 검증과 네트워크 요청의 중요성을 다시 확인했다. 앞으로 더 발전된 UX와 코드 품질을 목표로 개선해 나가야겠다!

createAddress.html

<!doctype html>
<html lang="en" data-theme="dark">
  <head>
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css"
    />
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>주소 등록</title>
  </head>
  <body>
    <main class="container">
      <header>
        <h1>주소 등록</h1>
        <a href="getAddress.html" role="button">주소 목록으로 이동</a>
      </header>
      <form id="addressForm">
        <label for="addressName">주소 이름</label>
        <input
          type="text"
          id="addressName"
          placeholder="주소 이름을 입력하세요"
          required
        />

        <label for="address">주소</label>
        <input
          type="text"
          id="address"
          placeholder="주소를 입력하세요"
          required
        />

        <button type="submit">등록하기</button>
      </form>
    </main>
    <script src="js/createAddress.js" defer></script>
  </body>
</html>

createAddress.js

const addressForm = document.querySelector('#addressForm');

// 주소 등록 이벤트
addressForm.addEventListener('submit', async (e) => {
  e.preventDefault();

  const addressName = document.querySelector('#addressName').value.trim();
  const address = document.querySelector('#address').value.trim();

  if (!addressName || !address) {
    alert('모든 필드를 입력해주세요.');
    return;
  }

  try {
    // 기존 주소 개수 확인
    const countResponse = await fetch('api/users/me/addresses', {
      method: 'GET',
      headers: {
        Authorization: `Bearer ${localStorage.getItem('accessToken')}`,
      },
    });

    if (!countResponse.ok) {
      throw new Error('주소 개수를 확인하지 못했습니다.');
    }

    const { data: addresses } = await countResponse.json();
    if (addresses.length >= 5) {
      alert('최대 5개의 주소만 등록할 수 있습니다.');
      return;
    }

    // 주소 등록 요청
    const response = await fetch('api/users/me/addresses', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${localStorage.getItem('accessToken')}`,
      },
      body: JSON.stringify({ addressName, address }),
    });

    if (!response.ok) {
      throw new Error('주소 등록에 실패했습니다.');
    }

    alert('주소가 등록되었습니다.');
    window.location.href = 'getAddress.html'; // 조회 페이지로 이동
  } catch (error) {
    console.error('등록 오류:', error);
    alert(error.message || '오류가 발생했습니다.');
  }
});
profile
Node.js 7기

0개의 댓글