diff --git "a/\353\245\230\353\257\270\354\204\261/3\354\243\274\354\260\250 \354\213\244\354\212\265/src/js/api/index.js" "b/\353\245\230\353\257\270\354\204\261/3\354\243\274\354\260\250 \354\213\244\354\212\265/src/js/api/index.js" new file mode 100644 index 0000000..8775343 --- /dev/null +++ "b/\353\245\230\353\257\270\354\204\261/3\354\243\274\354\260\250 \354\213\244\354\212\265/src/js/api/index.js" @@ -0,0 +1,89 @@ +const BASE_URL = "http://localhost:3000/api"; + +const HTTP_METHOD = { + POST(data) { + return { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(data), + }; + }, + PUT(data) { + return { + method: "PUT", + headers: { + "Content-Type": "application/json", + }, + body: data ? JSON.stringify(data) : null, + }; + }, + DELETE(data) { + return { + method: "DELETE", + headers: { + "Content-Type": "application/json", + }, + body: null, + }; + }, +}; + +const request = async (url, option) => { + const response = await fetch(url, option); + if (!response.ok) { + alert("에러가 발생했습니다."); + console.error(e); + } + + return response.json(); +}; + +const requestWithoutJson = async (url, option) => { + const response = await fetch(url, option); + if (!response.ok) { + alert("에러가 발생했습니다."); + console.error; + } + + // 없는 데이터를 json으로 변환하려고 하면 오류가 발생하기 때문에 함수 분리 + // response가 없는 형태는 내려주는 데이터가 없음 + return response; +}; + +const MenuApi = { + async getAllMenuByCategory(category) { + return request(`${BASE_URL}/category/${category}/menu`); + }, + + async createMenu(category, name) { + return request( + `${BASE_URL}/category/${category}/menu`, + HTTP_METHOD.POST({ name }) + ); + }, + + async updateMenu(category, name, menuId) { + return request( + `${BASE_URL}/category/${category}/menu/${menuId}`, + HTTP_METHOD.PUT({ name }) + ); + }, + + async toggleSoldOutMenu(category, menuId) { + return request( + `${BASE_URL}/category/${category}/menu/${menuId}/soldout`, + HTTP_METHOD.PUT() + ); + }, + + async deleteMenu(category, menuId) { + return requestWithoutJson( + `${BASE_URL}/category/${category}/menu/${menuId}`, + HTTP_METHOD.DELETE() + ); + }, +}; + +export default MenuApi; diff --git "a/\353\245\230\353\257\270\354\204\261/3\354\243\274\354\260\250 \354\213\244\354\212\265/src/js/index.js" "b/\353\245\230\353\257\270\354\204\261/3\354\243\274\354\260\250 \354\213\244\354\212\265/src/js/index.js" index 3825c58..0cd4dac 100644 --- "a/\353\245\230\353\257\270\354\204\261/3\354\243\274\354\260\250 \354\213\244\354\212\265/src/js/index.js" +++ "b/\353\245\230\353\257\270\354\204\261/3\354\243\274\354\260\250 \354\213\244\354\212\265/src/js/index.js" @@ -1,23 +1,34 @@ import { $ } from "./utils/dom.js"; -import store from "./store/index.js"; +import MenuApi from "./api/index.js"; + // TODO 서버 요청 부분 // - [x] 웹 서버를 띄운다. -// - [] 서버에 새로운 메뉴명이 추가될 수 있도록 요청한다. -// - [] 서버에 카테고리별 메뉴리스트를 불러온다. -// - [] 서버에 메뉴가 수정 될 수 있도록 요청한다. -// - [] 서버에 메뉴의 품절상태를 토글될 수 있도록 요청한다. -// - [] 서버에 메뉴가 삭제될 수 있도록 요청한다 +// - [x] 서버에 새로운 메뉴명이 추가될 수 있도록 요청한다. +// - [x] 서버에 카테고리별 메뉴리스트를 불러온다. +// - [x] 서버에 메뉴가 수정 될 수 있도록 요청한다. +// - [x] 서버에 메뉴의 품절상태를 토글될 수 있도록 요청한다. +// - [x] 서버에 메뉴가 삭제될 수 있도록 요청한다 // TODO 리팩터링 부분 -// - [] localStorage에 저장하는 로직은 지운다. -// - [] fetch 비동기 api를 사용하는 부분을 async await을 사용하여 구현한다. +// - [x] localStorage에 저장하는 로직은 지운다. +// - [x] fetch 비동기 api를 사용하는 부분을 async await을 사용하여 구현한다. // TODO 사용자 경험 -// - [] API 통신이 실패하는 경우에 대해 사용자가 알 수 있게 alert으로 예외처리를 진행한다. -// - [] 중복되는 메뉴는 추가할 수 없다. - -// fetch("url", option); -const BASE_URL = "http://localhost:3000/api"; +// - [x] API 통신이 실패하는 경우에 대해 사용자가 알 수 있게 alert으로 예외처리를 진행한다. +// - [x] 중복되는 메뉴는 추가할 수 없다. + +// 오늘의 회고 +// 1. 웹서버 연동 +// 2. BASE_URL 웹 서버 변수 먼저 선언 +// 3. 비동기 처리하는데 해당하는 부분이 어디인지 확인하고, 웹서버에 요청하게끔 코드 작성하기 +// 4. 서버에 요청한 후 데이터를 받아와서 화면에 렌더링 하기 +// 5. 리팩터링 +// - localStorage 부분 지우기 +// - API파일을 따로 만들어서 진행, +// - 페이지 렌더링과 관련해서 중복되는 부분들 제거, +// - 서버 요청 할 때 option 객체, +// - 카테고리 버튼 클릭시 콜백함수 분리 +// 6. 사용자 경험 부분 개선 function App() { // 메뉴가 여러개 이므로, 배열로서 초기화함 @@ -30,21 +41,28 @@ function App() { }; this.currentCategory = "espresso"; - this.init = () => { - // 로컬스토리지에 1개 이상의 데이터가 있다면, 있는 메뉴를 this.menu에 가져옴 - if (store.getLocalStorage()) { - this.menu = store.getLocalStorage(); - } + + this.init = async () => { + this.menu[this.currentCategory] = await MenuApi.getAllMenuByCategory( + this.currentCategory + ); render(); + initEventListeners(); }; - const render = () => { + const render = async () => { + this.menu[this.currentCategory] = await MenuApi.getAllMenuByCategory( + this.currentCategory + ); + // 메뉴별로 마크업을 하기 위해 map이라는 메서드 사용 const template = this.menu[this.currentCategory] - .map((menuItem, index) => { - return `