나의 개발 일지

javascript filter를 이용해서 일치하는 이름 배열 형태로 가져오기 (서울시 유치원 정보 사이트 프로젝트 ep.3)

designer DK 2024. 8. 27. 22:37
728x90

이번엔 디테일 페이지에 대한 작업이었다. 이전에 버튼 텍스트 콘텐츠로 서울시 구 이름을 전역변수로 저장, 리스트 페이지에서 그 저장된 값을 가져왔었는데 같은 방식으로 리스트페이지에서 클릭한 목록의 유치원 명을 clickedKinderName이라는 전역변수에 저장하고 그 값을 디테일 페이지에서 localStorage를 이용해서 로드하였다.

document.addEventListener("DOMContentLoaded", function() {
let clickedKinderName = localStorage.getItem('clickedKinderName');
 
if (clickedKinderName) {
searchDetail(clickedKinderName);
} else {
console.error("No Name found in localStorage.");
}
});

 

이번 디테일 페이지 작업의 핵심은 filter기능이었다. data.DATA 안에는 900개가 넘는 배열이 들어있는데 그 각 배열에 속한 kindername이라는 유치원명 중에 내가 클릭해서 가져온 clickedKinderName과 일치하는 유치원에 대한 데이터를 배열로 반환하였는데 그 방법으로 filter를 사용하였다.

function searchDetail(clickedKinderName){
fetch("./json/kinderGeneral.json")
.then((response) => response.json())
.then((data) => {

// filter: data.DATA 속 kindername이 특정 명칭(clickedKinderName)과 일치하는지 여부를 판단하고 일치하는 것을 배열로 반환
// .trim().toLowerCase()를 쓰면 띄어쓰기나 대소문자로 인한 불일치를 해소
let kinderInfos = data.DATA.filter((item) =>
item.kindername.trim().toLowerCase() === clickedKinderName.trim().toLowerCase()
);

 

문제 없는 코드를 작성했는데 데이터를 가져오지 못했었다. 당황해서 gpt의 도움을 받았는데 정확히는 무슨 문제인지는 모르겠으나  

.trim().toLowerCase()를 제안해주었고 이걸 붙여주니까 문제가 해결되었다. 이걸 사용하면 띄어쓰기나 대소문자로 인한 불일치를 해소할 수 있다고 한다.

 

클릭한 목록 유치원명과 일치되는 배열을 받았으므로 데이터를 html로 쭉 넣어주기만 하면 되어서 쉽게 풀리겠다고 생각했다. 실제로 데이터를 쭉 넣어주는건 거의 문제 없었다. 넣어주면서 하나 더 배운 부분이 있었는데 자바스크립트에서 변수에 저장된 숫자들을 연산해줄 때에는 이런식으로 Number라는 것을 앞에 붙여주어야 연산이 되었다. 

${Number(kinderInfoPick[0].clcnt3) + Number(kinderInfoPick[0].clcnt4)
+ Number(kinderInfoPick[0].clcnt5) + Number(kinderInfoPick[0].mixclcnt)
+ Number(kinderInfoPick[0].shclcnt)

 

이렇게 하면 가져오는 유치원 디테일 정보에 대한 변수인 kinderInfos가 하나일 때는 문제없이 페이지 구성이 가능했다. 문제는 kinderInfos 배열이 2개 이상일 때였다. 예를들어 강서구 버튼을 누르고 디테일 페이지까지 들어왔는데 같은 유치원 이름을 가진 0번 배열  송파구 유치원 디테일페이지에 표현되었다. 구에 대한 정보와 관련 없이 유치원 명으로만 검색된 정보였기 때문이다.

 

이를 해결하기 위해 clickedGuName도 디테일 페이지에 localStorage로 가져왔다.

document.addEventListener("DOMContentLoaded", function() {
let clickedGuName = localStorage.getItem('clickedGuName');
let clickedKinderName = localStorage.getItem('clickedKinderName');
 
if (clickedGuName, clickedKinderName) {
searchDetail(clickedGuName, clickedKinderName);
} else {
console.error("No Name found in localStorage.");
}
});

 

이리저리 방법을 찾아내어 filter와 include의 조합된 구문으로 클릭한 구 이름과 일치되는 배열만 따로 반환에 성공하였다.

function searchDetail(clickedGuName, clickedKinderName){
fetch("./json/kinderGeneral.json")
.then((response) => response.json())
.then((data) => {

// filter: data.DATA 속 kindername이 특정 명칭(clickedKinderName)과 일치하는지 여부를 판단하고 일치하는 것을 배열로 반환
// .trim().toLowerCase()를 쓰면 띄어쓰기나 대소문자로 인한 불일치를 해소
let kinderInfos = data.DATA.filter((item) =>
item.kindername.trim().toLowerCase() === clickedKinderName.trim().toLowerCase()
);

// kinderInfos에 들어있는 배열 정보 중 주소가 clickedGuName을 포함하는 배열만 반환
let kinderInfoPick = kinderInfos.filter((item) =>
item.addr.includes(clickedGuName));

 

 

그렇게해서 의도한대로 클릭한 유치원 명으로부터 디테일 정보를 추출하여 디테일 페이지에 넣어주는 작업에 성공하였다.

이로써 아주 기본적인 기능 구현은 완료된 것 같고 이어서 부가 기능들인 써치인풋으로 유치원 목록 검색, 목록 페이지네이션, 디테일페이지 그래프 표현. 이렇게 목표 기능구현이 남았다.