2025년 1월 20일

김동환·2025년 1월 20일

오늘의 코드

TIL (Today I Learned) - 주소 수정 및 삭제 기능 구현

오늘 배운 것

오늘은 주소 수정과 삭제 기능을 구현하면서, HTML, JavaScript, 그리고 API 통신을 활용하는 방법을 익혔다. 주요 학습 내용을 아래에 정리했다.


1. 주소 수정 기능 구현 (patchAddress.html & patchAddress.js)

구현 내용

  1. HTML 구조

    • patchAddress.html에서는 주소 수정 폼을 제공.
    • 사용자로부터 입력받은 주소 이름과 주소를 수정할 수 있도록 입력 필드와 제출 버튼을 배치.
  2. JavaScript 로직

    • patchAddress.js에서 두 가지 주요 기능 구현:
      1. 기존 주소 불러오기
        • fetch API를 사용해 서버에서 주소 데이터를 가져오고, 입력 필드에 미리 채워줌.
      2. 주소 수정
        • 폼 제출 시, PATCH 요청으로 입력된 데이터를 서버로 전송.
        • 수정 성공 시 사용자에게 알림을 띄우고, 주소 목록 페이지로 리디렉션.

배운 점

  • fetch API를 사용한 HTTP 요청과 응답 처리 방법.
  • 사용자 경험을 개선하기 위해 초기 데이터를 폼에 미리 채워주는 UX 구현.
  • 폼의 submit 이벤트를 차단하고 비동기 로직을 실행하는 패턴.

2. 주소 삭제 기능 구현 (deleteAddress.html & deleteAddress.js)

구현 내용

  1. HTML 구조

    • deleteAddress.html에서는 사용자에게 삭제 여부를 확인하는 간단한 UI 제공.
    • 삭제 버튼과 취소 버튼을 배치해 사용자 선택 제공.
  2. JavaScript 로직

    • deleteAddress.js에서 삭제 버튼 클릭 이벤트 처리:
      • DELETE 요청을 서버로 보내 주소를 삭제.
      • 삭제 성공 시 사용자에게 알림을 띄우고, 주소 목록 페이지로 리디렉션.

배운 점

  • DELETE 메서드를 사용해 서버에서 리소스를 삭제하는 방법.
  • 버튼 클릭 이벤트를 활용해 사용자 동작을 트리거하는 방식.

3. 공통적으로 배운 점

  1. API 호출 시 필요한 인증 처리

    • Authorization 헤더를 통해 Bearer 토큰을 서버로 전달.
    • localStorage에서 액세스 토큰을 가져와 사용.
  2. 에러 처리

    • 서버 응답이 실패한 경우 (response.okfalse인 경우), 사용자에게 오류 메시지를 출력.
    • try-catch 블록을 활용해 네트워크 오류를 처리.
  3. URL 파라미터 활용

    • URLSearchParams를 사용해 URL의 쿼리 파라미터에서 id 값을 추출.
    • 동적으로 특정 리소스에 접근하는 데 활용.

개선할 점 및 다음 학습 계획

  1. 코드 재사용성 개선

    • fetch 호출 로직이 반복되므로, 공통 함수로 분리해 재사용성을 높이는 방법 학습.
  2. UI 개선

    • 성공 및 실패 알림 메시지를 모달 창으로 변경하여 더 직관적인 UX 제공.
  3. API 호출 최적화

    • 에러 로그를 서버로 전송하는 방식을 추가해 디버깅 효율성을 높이는 방법 연구.

오늘의 느낀 점

이번 학습을 통해 RESTful API와 비동기 프로그래밍의 기본기를 더 탄탄히 다질 수 있었다. 또한, 사용자 친화적인 인터페이스와 HTTP 메서드의 적절한 사용이 얼마나 중요한지 깨달았다. 앞으로도 더 효율적인 코드 작성과 UX 개선에 신경 쓰며 프로젝트를 발전시켜 나가야겠다.

patchAddress.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="patchForm">
        <label for="addressName">주소 이름</label>
        <input type="text" id="addressName" required />
        <label for="address">주소</label>
        <input type="text" id="address" required />
        <button type="submit">수정</button>
      </form>
    </main>
    <script src="js/patchAddress.js" defer></script>
  </body>
</html>

patchAddress.js

const urlParams = new URLSearchParams(window.location.search);
const addressId = urlParams.get('id');
const patchForm = document.querySelector('#patchForm');
const addressNameInput = document.querySelector('#addressName');
const addressInput = document.querySelector('#address');

// 기존 주소 불러오기
const fetchAddress = async () => {
  try {
    const response = await fetch(`api/users/me/addresses/${addressId}`, {
      method: 'GET',
      headers: {
        Authorization: `Bearer ${localStorage.getItem('accessToken')}`,
      },
    });

    if (!response.ok) throw new Error('주소를 불러올 수 없습니다.');

    const address = await response.json();
    addressNameInput.value = address.data.addressName;
    addressInput.value = address.data.address;
  } catch (error) {
    console.error('주소 불러오기 오류:', error);
  }
};

// 주소 수정
patchForm.addEventListener('submit', async (e) => {
  e.preventDefault();

  try {
    const response = await fetch(`api/users/me/addresses/${addressId}`, {
      method: 'PATCH',
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${localStorage.getItem('accessToken')}`,
      },
      body: JSON.stringify({
        addressName: addressNameInput.value,
        address: addressInput.value,
      }),
    });

    if (!response.ok) throw new Error('주소 수정에 실패했습니다.');

    alert('주소가 수정되었습니다.');
    window.location.href = 'getAddress.html';
  } catch (error) {
    console.error('주소 수정 오류:', error);
  }
});

// 초기 데이터 로드
fetchAddress();

deleteAddress.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>
      <p>정말 이 주소를 삭제하시겠습니까?</p>
      <button id="confirmDelete">삭제</button>
      <button onclick="window.location.href='getAddress.html'">취소</button>
    </main>
    <script src="js/deleteAddress.js" defer></script>
  </body>
</html>

deleteAddress.js

const urlParams = new URLSearchParams(window.location.search);
const addressId = urlParams.get('id');
const confirmDelete = document.querySelector('#confirmDelete');

confirmDelete.addEventListener('click', async () => {
  try {
    const response = await fetch(`api/users/me/addresses/${addressId}`, {
      method: 'DELETE',
      headers: {
        Authorization: `Bearer ${localStorage.getItem('accessToken')}`,
      },
    });

    if (!response.ok) throw new Error('주소 삭제에 실패했습니다.');

    alert('주소가 삭제되었습니다.');
    window.location.href = 'getAddress.html';
  } catch (error) {
    console.error('주소 삭제 오류:', error);
  }
});
profile
Node.js 7기

0개의 댓글