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");
addEventListene
r로 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 RegEx
p에 매개변수로 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에 검색한 내용)이 하이라이팅되고 있는 모습