이번 프로젝트에서 검색기능과 자동완성기능, 인기뉴스를 정렬해도 보여주는 기능을 맡았다.
오늘은 검색기능을 만들었으며, 쉬워보였지만 많은 난관이 있었다....
결국 이것 저것 막 가져가 붙여보면서 해결했다.
검색기능
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에 통째로 넣는다.
자잘한 어려움이 있었지만 튜터님들과 동기들, 한땀한땀 코드를 바꿔가면서 실행시키는 장인정신과 구글링으로 해결했다..
역시 프로젝트를 하면서 직접 부딪치니 재밌다.
어려움을 이겨내는 자세... 너무 멋집니다 ㅎㅎ