
Ajax 비동기 통신 fetch를 이용해서 데이터를 받아와 화면에 출력 및 검색해보자!

const endpoint =
"https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json";
endpoint json 데이터파일
해당 변수를 담기 위하여 cities라는 빈배열을 선언하고 그 배열안데 json파일을 담아보자
const cities = [];해당 json 데이터서버와 통신하기 위해 fetch라는 메서드를 사용한다
❓ 여기서 fetch() 메서드란?
네트워크에서 리소스를 취득하는 절차를 시작하고, 응답이 사용 가능해지면 이행하는 프로미스를 반환한다 ➡️promise는 요청에 대한 응답을 나타내는Response객체로 이행한다


endpoint를 fetch메서드를 사용했더니 promise 객체를 반환하는 모습
promise객체는 어떻게 가공해야할까❓promise로 반환한 객체에 대해 .then을 참조하면 해당 data의 Response객체를 확인해볼 수 있다


promise 객체로 가져온 endpoint json 데이터를 .then으로 1차 가공한 모습
.then 사용만으로는 현재 데이터의 정보를 받아 올 수 없다
JSON.parse()메서드는 JSON 문자열의 구문을 분석 후 ➡️ Javascript 값이나 객체를 생성한다

그럼 .then으로 1차 가공한 blob객체를 JSON.parse()로 파싱하면❓

에러가 나타나는 이유는 무엇일까❓


blob.json() 객체의 console.log


이렇게 data 변수 내에 1000개의 json형식의 데이터타입이 담겨져 있는걸 볼 수 있다
cities에 파싱한 data를 push 해보자

🤔 하지만 이렇게 cities에 바로 data를 push해버리면 배열 안에 배열로 json 데이터들이 담겨지게 된다 이런 이유로 data를 spread 연산자를 사용해 전개해야한다

spread 연산자를 사용해서 전개한 모습

function findMatches(wordToMatch, cities) {
// 여기서 우리는 주에 있는 도시가 검색된 것과 일치하는지 알아내야함
return cities.filter((place) =>
const regex = new RegExp(wordToMatch, "gi");
// place의 city 및 place.state 값이 검색와 일치하는지 확인
return place.city.match(regex) || place.state.match(regex);
});
}
findMatch() 함수에 매개변수로 wordToMatch:검색어와 cities:도시목록을 매개변수로 받는다filter 함수로 cities 배열에서 새로운 배열을 생성한다new RegExp로 정규 표현식을 생성하고new RegExp에 매개변수로 검색어와, gi라는 매개변수를 전달한다match 함수를 사용하게 되는데, match란 ❓match() : 문자열이 정규식과 매치되는 부분을 검색하는 메서드 place의 city 및 place.state 값이 검색와 일치하는지 확인한다
findMatch() 함수에 전달인자로 'Bos'를 전달한 모습 city에 Bos라는 문자열이 포함되어있는 도시를 찾을 수 있다
querySelector로 html의 form과 input을 읽어온다
const searchInput = document.querySelector(".search");
const suggestions = document.querySelector(".suggestions");
addEventListener로 change이벤트와 keyup이벤트가 일어났을 경우displayMatches함수가 실행될 수 있도록 핸들링 한다 searchInput.addEventListener("change", displayMatches);
searchInput.addEventListener("keyup", displayMatches);
❓ displayMatch의 this.value는?
function displayMatches() {
console.log(this.value);
}


해당 this.value는 곧 내가 input에서 입력한 값이 value로 displayMathch()함수에서 쓰여진다는 의미이다
this.value를 이용해서 displayMatch() 함수에서 만들어둔 findMatch() 함수를 변수로 만들어 적용하면❓ function displayMatches() {
const matchArray = findMatches(this.value, cities);
console.log(matchArray);
}


this.value(내가 input에 입력한 값)을 전달인자로 findMatches()에 전달하면 내가 입력한 값이 변수로 할당되어 읽어올 수 있게된다!
matchArray 변수를 이용해 element node를 생성해야 한다matchArray의 배열에 대해 map()함수를 사용해 새로운 배열을 생성한다const html = matchArray
.map((place) => {
return `
<li>
<span class="name">${place.city}, ${place.state}</span>
<span class="population">${place.population}</span>
</li>
`;
})
.join("");
❓
join()을 쓰는 이유?
join(): 배열의 모든 요소를 연결해 하나의 문자열로 만듬
map으로 만든 새배열 place에 join("")을 안쓰게 된다면
생성한 새로운 list의 끝에 ,가 붙어버려 보기 이상해진다..

html 변수를 suggestion(ul태그) 내의 innerHTML로 붙인다suggestions.innerHTML = html;
suggestion에 html를 넣고, value를 넣은 모습
✨ this.value에 highlights 효과 넣어주기
displayMatches() 함수내부에 new RegExp에 매개변수로 this.value와 "gi"값을 넣어주고replace()한다❓ replace() 메서드란?
패턴에 일치하는 일부 또는 모든 부분이 교체된 새로운 문자열을 반환
패턴 : 정규표현식
const cityName = place.city.replace(regex, `<span class="hl">${this.value}</span>`);
${place.city}부분을 ${cityName}로 교체한다
${place.city} ➡️ ${cityName}

this.value가(내가 input에 검색한 내용)이 하이라이팅되고 있는 모습