TIL 16. 검색기능 만들기 (feat. firebase)

isk·2022년 11월 21일
0

TIL

목록 보기
16/122
post-custom-banner

이번 프로젝트에서 검색기능과 자동완성기능, 인기뉴스를 정렬해도 보여주는 기능을 맡았다.
오늘은 검색기능을 만들었으며, 쉬워보였지만 많은 난관이 있었다....
결국 이것 저것 막 가져가 붙여보면서 해결했다.

검색기능

import { dbService } from './firebase.js';
import {
  collection,
  orderBy,
  query,
  getDocs,
} from 'https://www.gstatic.com/firebasejs/9.14.0/firebase-firestore.js';

firebase를 import해준다.
그리고 그 아래, 아래의 코드를 넣었다.

export async function getSearchList(event) {
  event.preventDefault();

  let searchObjList = [];

  const q = query(collection(dbService, 'posts'), orderBy('postTitle', 'desc'));
  const querySnapshot = await getDocs(q);

  querySnapshot.forEach((doc) => {
    const searchObj = {
      id: doc.id,
      ...doc.data(),
    };
    searchObjList.push(searchObj);
  });

export는 해당 함수를 다른 파일에서 실행시킬 수 있게 해주는데, 실행시킬 파일에서 import를 해줘야한다.
async는 await와 짝꿍이다.
함수 앞에 async를 써주고, 메서드에 await를 써준다.
async가 붙은 함수는 동기적으로 실행된다.
velog 게시물 중 async와 await에 대해 쓴 글이 있어서 이해하는데 어렵지 않았다.

코드 설명을 하자면, searchObjList라는 변수에 빈 배열을 만든다.
해당 변수에는 dbService의 데이터들이 들어가게 되는데,
dbService는 getFirestore를 import하여 dbService 변수에 담은 것이다.
q라는 변수에 query를 담는데, query는 어떤 데이터를 가져올 건지 정한다고 보면 된다. (요청과는 다른 것 같다.)
query 괄호 안의 collection에 접근하여 dbService로 posts 컬렉션 쿼리를 정한다.
querySnapshot이라는 변수에 getDocs로 데이터를 가져오는데, getDocs의 괄호 속 q 조건에 맞는 데이터만 가져온다.

짧게 설명하자면,
query() : 괄호 안에 수 많은 데이터 중 어떤 데이터를 가져올지 정한다.
getDocs() : 괄호 안에 query가 들어가는데, query에 맞는 데이터를 가져온다.

forEach문을 사용하여 querySnapshot에 담긴 데이터를 하나하나 꺼내어 실행문을 실행시킨다.
searchObj에 객체 형식으로 데이터를 담고, 처음에 만들어두었던 searchObjList에 push한다.

  const searchList = document.querySelector('.post-container');
  searchList.innerHTML = '';
  const searchvalue = document.querySelector('#searchvalue');
  
  searchObjList.forEach((searchObj) => {
    const post = document.querySelector('.post-container');
    if (searchvalue.value.toLowerCase() === searchObj.artistTag.toLowerCase()) {
      const temp_html = `<article class="posts">
	<div class="post-header">
		<img
			src="./assets/imgs/8C60C9E7-0049-44F2-A97F-CDB5E868B1E9_1_105_c.jpeg"
			alt=""
			class="profile-img"
		/>
		<div class="post-title">
			<div class="post-title-top">
				<div class="post-title-top-name">
					<p>
						<a class="user-nickname">${searchObj.userNickname}</a>님이
						<span class="tags">장소</span>를 공유했습니다.
					</p>
				</div>
			</div>
			<p class="post-title-bottom">
				${searchObj.artistTag}의 팬 @jeremy-kr • ${searchObj.postTime}
			</p>
		</div>
	</div>
	<div class="post-main">
		<div class="post-main-title">
			<span
				>${searchObj.postTitle}</span
			>
		</div>
		<img
			src="./assets/imgs/E7364DD7-EDFA-47A3-96D0-CFE41619146A_1_102_o.jpeg"
			alt=""
			class="post-main-img"
		/>
		<div class="post-main-text">
		${searchObj.postText}
		</div>
	</div>
</article>`;
      const div = document.createElement('div');
      div.innerHTML = temp_html;
      post.appendChild(div);
    }
  });
}

가져온 데이터들을 페이지에 뿌려줘야한다.
데이터와 비교할 searchvalue 변수를 만들어주고, html을 뿌리기 위한 searchList 변수를 만든다.
검색을 하면 searchList.innerHTML = '';로 기존 검색 게시물 리스트를 삭제한다.

searchObjList를 forEach를 사용하여, 데이터를 하나씩 꺼내서 if문으로 검색창에 적힌 value값과 비교한다.
toLowerCase를 사용해서 대소문자의 구문을 소문자로 통일했다.
그리고 나서 div 태그를 만들어주고, 그 div에 temp_html을 넣고, 그것들을 post변수가 가리키는 html에 통째로 넣는다.


자잘한 어려움이 있었지만 튜터님들과 동기들, 한땀한땀 코드를 바꿔가면서 실행시키는 장인정신과 구글링으로 해결했다..

역시 프로젝트를 하면서 직접 부딪치니 재밌다.

post-custom-banner

2개의 댓글

comment-user-thumbnail
2022년 11월 22일

어려움을 이겨내는 자세... 너무 멋집니다 ㅎㅎ

1개의 답글