인프런 커뮤니티 질문&답변
최종프로젝트 상세페이지 출력 오류 문의드립니다!
해결된 질문
작성
·
96
·
수정됨
0
세션 9. 최종 프로젝트
cityDetail 개발-2 에서
https://trip-wiki-api.vercel.app/ 강사님이 알려주셨던 링크에는 상세페이지 이미지와 받는 정보가 없습니다! 어떻게 상세페이지를 출력할 수 있나요? Japan을 검색창에서 검색하고 상세페이지를 눌렀지만 아무런 정보가 출력되지 않고 있습니다!


import Header from "./components/Header.js"; import RegionList from "./components/RegionList.js"; import CityList from "./components/CityList.js"; import CityDetail from "./components/CityDetail.js"; import { request, requestCityDetail } from "./components/api.js"; export default function App($app) { const getSortBy = () => { if (window.location.search) { return window.location.search.split("sort=")[1].split("&")[0]; } return "total"; }; const getSearchWord = () => { if (window.location.search && window.location.search.includes("search=")) { return window.location.search.split("search=")[1]; } return ""; }; this.state = { startIdx: 0, sortBy: getSortBy(), region: window.location.pathname.replace("/", ""), searchWord: getSearchWord(), cities: "", currentPage: window.location.pathname, }; const renderHeader = () => { new Header({ $app, initialState: { currentPage: this.state.currentPage, sortBy: this.state.sortBy, searchWord: this.state.searchWord, }, handleSortChange: async (sortBy) => { const pageUrl = `/${this.state.region}?sort=${sortBy}`; history.pushState( null, null, this.state.searchWord ? pageUrl + `&search=${this.state.searchWord}` : pageUrl ); const cities = await request( 0, this.state.region, sortBy, this.state.searchWord ); this.setState({ ...this.state, startIdx: 0, sortBy: sortBy, cities: cities, }); }, handleSearch: async (searchWord) => { history.pushState( null, null, `/${this.state.region}?sort=${this.state.sortBy}&search=${searchWord}` ); const cities = await request( 0, this.state.region, this.state.sortBy, searchWord ); this.setState({ ...this.state, startIdx: 0, cities: cities, searchWord: searchWord, }); }, }); }; const renderRegionList = () => { new RegionList({ $app, initialState: this.state.region, handleRegion: async (region) => { history.pushState(null, null, `/${region}?sort=total`); const cities = await request(0, region, "total"); this.setState({ ...this.state, startIdx: 0, sortBy: "total", region: region, cities: cities, searchWord: "", currentPage: `/${region}`, }); }, }); }; const renderCityList = () => { new CityList({ $app, initialState: this.state.cities, handleItemClick: async (id) => { history.pushState(null, null, `/city/${id}`); this.setState({ ...this.state, currentPage: `/city/${id}`, }); }, handleLoadMore: async () => { const newStartIdx = this.state.startIdx + 40; const newCities = await request( newStartIdx, this.state.region, this.state.sortBy ); this.setState({ ...this.state, startIdx: newStartIdx, cities: { ...this.state.cities, cities: [...this.state.cities.cities, ...newCities.cities], isEnd: newCities.isEnd, }, }); }, }); }; const renderCityDetail = async (cityId) => { try { const cityDetailData = await requestCityDetail(cityId); new CityDetail({ $app, initialState: cityDetailData }); } catch (err) { console.log(err); } }; const render = async () => { const path = this.state.currentPage; $app.innerHTML = ""; // 상세 페이지로 이동 if (path.startsWith("/city/")) { const cityId = path.split("/city/")[1]; renderHeader(); renderCityDetail(cityId); } else { renderHeader(); renderRegionList(); renderCityList(); } }; this.setState = (newState) => { this.state = newState; render(); }; const init = async () => { const path = this.state.currentPage; // 메인 페이지 if (!path.startsWith("/city")) { const cities = await request( this.state.startIdx, this.state.region, this.state.sortBy, this.state.searchWord ); this.setState({ ...this.state, cities: cities, }); } // 상세페이지 else { render(); } }; window.addEventListener("popstate", async () => { const urlPath = window.location.pathname; const prevRegion = urlPath.replace("/", ""); const prevPage = urlPath; const prevSortBy = getSortBy(); const prevSearchWord = getSearchWord(); const prevStartIdx = 0; const prevCities = await request( prevStartIdx, prevRegion, prevSortBy, prevSearchWord ); this.setState({ ...this.state, startIdx: prevStartIdx, sortBy: prevSortBy, region: prevRegion, currentPage: prevPage, searchWord: prevSearchWord, cities: prevCities, }); }); init(); } //API.js 코드입니다!export default function CityDetail({ $app, initialState }) { this.state = initialState; this.$target = document.createElement("div"); this.$target.className = "city-detail"; $app.appendChild(this.$target); const getScoreColor = (score) => { // let scoreNumber = parseInt(score); if (score >= 4) return "green"; if (score >= 3) return "yellow"; return "red"; }; this.template = () => { let cityData = this.state.CityDetail; let temp = ``; if (cityData) { temp = `<div class="image-banner"> <img src="${cityData.image}"/> <div class="city-name"> <div class="city">${cityData.city}</div> <div class="country">${cityData.region} / ${cityData.country}</div> </div> </div> <div class="progress-container"> <div class="info-item"> <div class="label">⭐ Total Score</div> <div class="progress-bar" score-color="${getScoreColor( cityData.total )}" style="--score:${cityData.total * 20}%"></div> </div> <div class="info-item"> <div class="label">💵 Cost</div> <div class="progress-bar" score-color="${getScoreColor( cityData.info.cost )}" style="--score:${cityData.info.cost * 20}%"></div> </div> <div class="info-item"> <div class="label">😆 Fun</div> <div class="progress-bar" score-color="${getScoreColor( cityData.info.fun )}" style="--score:${cityData.info.fun * 20}%"></div> </div> <div class="info-item"> <div class="label">🚓 Safety</div> <div class="progress-bar" score-color="${getScoreColor( cityData.info.safety )}" style="--score:${cityData.info.safety * 20}%"></div> </div> <div class="info-item"> <div class="label">🌐 Internet</div> <div class="progress-bar" score-color="${getScoreColor( cityData.info.internet )}" style="--score:${cityData.info.internet * 20}%"></div> </div> <div class="info-item"> <div class="label">💨 Air Condition</div> <div class="progress-bar" score-color="${getScoreColor( cityData.info.air )}" style="--score: ${cityData.info.air * 20}%"></div> </div> <div class="info-item"> <div class="label">🍜 Food</div> <div class="progress-bar" score-color="${getScoreColor( cityData.info.food )}" style="--score: ${cityData.info.food * 20}%"></div> </div> </div> `; } return temp; }; this.render = () => { this.$target.innerHTML = this.template(); }; /* this.setState = (newState) => { this.state = newState; this.render(); }; */ this.render(); } //cityDetail.js 상세페이지 코드입니다!
답변 2
0
안녕하세요 안연수님 🙂
https://trip-wiki-api.vercel.app/ 강사님이 알려주셨던 링크에는 상세페이지 이미지와 받는 정보가 없습니다!
라고 해주셨는데요, [9.최종프로젝트-CityDetail 개발-1] 강의에서 상세페이지 정보를 어떻게 받는지 소개하고 있으니, 해당 강의를 다시 수강해보시는 것을 추천드립니다.
강의를 다시 수강해보신 다음, api.js에 알맞은 api 호출 코드를 작성해주시면 잘 동작할 것 같습니다! 그럼에도 오류가 발생한다면, 다시 질문 작성해주세요. 감사합니다!
0
안녕하세요, 인프런 AI 인턴입니다. 안연수님. 질문 주셔서 감사합니다.
현재 작성하신 코드에서 “상세 페이지 출력 오류” 문제를 겪고 계신 것으로 보이네요. 이는 여러 가지 원인으로 인해 발생할 수 있습니다. 아래에 몇 가지 확인할 수 있는 사항과 해결 방법을 제공하겠습니다.
API의 응답 데이터 확인:
requestCityDetail함수 호출 시 반환되는 데이터가 올바른지, 콘솔에서 확인해보세요. 이를 통해 서버에서 데이터를 제대로 받아오고 있는지 확인할 수 있습니다.
- 콘솔에서
console.log(cityDetailData)를 추가하여 얻어오는 데이터가 무엇인지 반드시 확인하세요.
API 요청 URL:
requestCityDetail함수 내의 API 요청 URL이 정확한지 확인해 주세요. 현재 사용 중인 API가 유효한지를 체크해야 합니다. API가 잘못 설정되면 데이터가 올바르게 로딩되지 않습니다.
데이터 구조 및 바인딩:
CityDetail컴포넌트 내this.state.CityDetail이 올바른 데이터 구조를 가지고 있는지, 데이터가 존재하는지 확인해보세요.
- API로부터 받아오는 데이터의 구조가
CityDetail컴포넌트가 기대하는 것과 같은지 확인하고 코드에서 올바르게 바인딩되었는지 확인해주시기 바랍니다.
연결 문제:
renderCityDetail함수에서 새로고침 후에도 정상적으로 데이터를 렌더링할 수 있도록 이벤트 핸들러와 관련된 코드가 잘 연결되어 있는지 확인하세요.
에러 핸들링:
- 코드를 디버깅하는 과정에서 try-catch 구문을 사용하여 발생 가능한 에러를 잡고 적절한 에러 메시지를 추가하여 디버깅하세요.
- 코드를 디버깅하는 과정에서 try-catch 구문을 사용하여 발생 가능한 에러를 잡고 적절한 에러 메시지를 추가하여 디버깅하세요.
이를 해결하는 과정에서 API 요청 부분과 데이터 가공 로직을 특히 주의 깊게 살펴봐야 합니다. 아래는 전반적인 안내 링크입니다:
- Trip Wiki 프로젝트 API 사용법 및 디버깅 - API 관련 디버깅에 관한 문제를 다루는 질문입니다.
문제 해결에 도움이 되기를 바라며, 이러한 점검 후에도 문제가 해결되지 않으면 코드 및 세부 사항을 공유해 주세요. 추가적인 도움을 드릴 수 있도록 하겠습니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드립니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.






api.js 코드에 대한 Detail API 부분 코드 에러 문제에 대해서 문의드립니다! 혹시 잘못된 코드가 있나요? 어떠한 이유로 Detail API 코드 부분이 인식되지 않는 지 문의드립니다!