본문 바로가기

JavaScript30 Challenge

[JavaScript30] Day 6

Type Ahead

 

자동 완성 기능 만들기

검색어의 일부를 입력했을 때 나올 수 있는 검색 결과를 미리 보여주는 기능이다.

 

// 도시, 주, 인구 등의 자료가 들어있는 파일
const endpoint = 'https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json';

const cities = [];

 

//보통의 메서드를 사용하는 방식
fetch(endpoint, function() {
	console.log(data);
});

fetch는 일반 함수를 사용하는 것과는 약간 다른 형식으로 사용한다.

fetch는 promise를 return하기 때문에 아래와 같이 보통 함수와 약간은 다른 방식으로 작동한다.

const prom = fetch(endpoint);
consoel.log(prom);

fetch(endpoint).then(blob => console.log(blob));
fetch(endpoint)
  .then(blob => blob.json())
  .then(data => cities.push(...data))

 

...data는 spread syntax문법으로 

.then(data => cities.push(data))인 경우

 

.then(data => cities.push(...data))인 경우

아래의 경우의 데이터 1000개의 데이터에 추가된 것을 볼 수 있다.

 

function findMatches(wordToMatch, cities) {
  return cities.filter(place => {
    // 여기에서 검색된것과 일치하는지 알아냄 
    // return place.city.match(/box/i) // 이렇게 검색할 수는 없음, 단어가 계속 바뀌니까
    // return place.city.match(/wordToMatch/i) // wordToMatch라는 단어를 찾음
    const regex = new RegExp(wordToMatch, 'gi');
    return place.city.match(regex) || place.state.match(regex);
  });
}

 

function displayMatches() {
  console.log(this.value);
}

const searchInput = documnet.que    const searchInput = document.querySelector('.search');
const suggestions = document.querySelector('.suggestions');

searchInput.addEventListener('change', displayMatches);
searchInput.addEventListener('keyup', displayMatches);

change만 있는 경우 테스트는 단어를 입력 후 개발자도구창을 클릭하면 된다. (엔터 X)

 

displayMatches라는 match가 이루어지는 함수를 만든다.

function displayMatches() {
  const matchArray = findMatches(this.value, cities);
  const html = matchArray.map(place => {
    return `
    <li>
      <span class="name">${place.city}, ${place.state}</span>
      <span class="population">${place.population}</span>
    </li>
    `;
  }).join('');
  suggestions.innerHTML = html;
}

 

displayMatches()를 아래와 같이 수정할 수 있다.

function displayMatches() {
  // console.log(this.value)
  const matchArray = findMatches(this.vlaue, cities);
  // console.log(matchArray)
  const html = matchArray.map(place => {
    const regex = new RegExp(this.value, 'gi');
    const cityName = place.city.replace(regex, `<span class="hl">${this.value}</span>`)
    const stateName = place.state.replace(regex, `<span class="hl">${this.value}</span>`)
    return `
    <li>
      <span class="name">${cityName}, ${stateName}</span>
      <span class="population">${numberWithCommas(place.population)}</span>
    </li>
    `;
  }).join('');
  suggestions.innerHTML = html;
}

 

천의 자릿수 마다 콤마(,) 표시

function numberWithCommas(x) {
  return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}

 

최종 코드

const endpoint = 'https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json';

const cities = [];
fetch(endpoint)
  .then(blob => blob.json())
  .then(data => cities.push(...data));

function findMatches(wordToMatch, cities) {
  return cities.filter(place => {
    const regex = new RegExp(wordToMatch, 'gi');
    return place.city.match(regex) || place.state.match(regex)
  });
}

function numberWithCommas(x) {
  return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}

function displayMatches() {
  const matchArray = findMatches(this.value, cities);
  const html = matchArray.map(place => {
    const regex = new RegExp(this.value, 'gi');
    const cityName = place.city.replace(regex, `<span class="hl">${this.value}</span>`);
    const stateName = place.state.replace(regex, `<span class="hl">${this.value}</span>`);
    return `
      <li>
        <span class="name">${cityName}, ${stateName}</span>
        <span class="population">${numberWithCommas(place.population)}</span>
      </li>
    `;
  }).join('');
  suggestions.innerHTML = html;
}

const searchInput = document.querySelector('.search');
const suggestions = document.querySelector('.suggestions');

searchInput.addEventListener('change', displayMatches);
searchInput.addEventListener('keyup', displayMatches);

 

 

 

 


Spread syntax

배열이나 문자열과 같이 반복 가능한 문자를 0개 이상의 인수 또는 요소로 확장하여, 0개 이상의 키-값의 쌍으로 객체로 확장시킬 수 있다.

 

iterable

protocol 은 JavaScript 객체들이, 예를 들어 for..of 구조에서 어떠한 value 들이 loop 되는 것과 같은 iteration 동작을 정의하거나 사용자 정의하는 것을 허용합니다. 다른 type 들(Object 와 같은)이 그렇지 않은 반면에, 어떤 built-in type 들은 Array 또는 Map 과 같은 default iteration 동작으로 built-in iterables 입니다.

 

fetch API

비동기 통신 방법으로 자체로 Promise 객체를 반환

fetch() : 네트워크에서 비동기 적으로 리소스를 가져오는 쉽고 논리적인 방법을 제공하는 전역 방법을 제공하는 메서드.

비동기 처리 : 특정 로직의 실행이 끝날 때까지 기다려주지 않고 나머지 코드를 먼저 실행하는 것

Promise : JavaScript 비동기 처리에 사용되는 객체

주로 서버에서 받아온 데이터를 화면에 표시할 때 사용

 

 

JavaScript30 강의를 보고 공부한 글입니다. (https://javascript30.com/)

'JavaScript30 Challenge' 카테고리의 다른 글

[JavaScript30] Day 8  (0) 2020.04.25
[JavaScript30] Day 7  (0) 2020.04.22
[JavaScript30] Day 5  (0) 2020.04.18
[JavaScript30] Day 4  (0) 2020.04.18
[JavaScript30] Day 3  (0) 2020.04.16