일주일, 아니 4일동안 프로젝트를 마무리하며 많은 일들이 있었다.
처음 써보는 Firebase와 익숙해지기 위한 몸부림부터, 수많은 undefined와의 싸움들이 그와 같다.
어제 그러니까 27일은 거의 잠을 자지 않았다. 아니 못했다는 게 맞는 표현일 것 같다.
Firebase의 DB를 이용한 CRUD 기능중
Update기능과 Delete기능과의 싸움이 계속됐다.
deleteDoc 이 최우선이었다. 등록된 Comment를 삭제하는 방식만 제대로 구현해낸다면
수정 즉 update하는 기능은 따라오는 것이기 때문이었다.
오류의 중심에 있는것은 무작위로 생성되는 ID였다.
처음 addDoc을 진행 할 때, 특정한 ID를 기입하지 않았기 때문에 이 부분은 Firebase자체에서 무작위 ID를 등록하게된다.
저 ID를 알아내야 Comment를 수정 할 수 있다.
addDoc으로 문서를 생성할 때 무작위의 ID가 생성된다. 거기서 힌트를 얻었다
async function renderComments() {
const querySnapshot = await getDocs(collection(db, 'storyCard1'));
$('#card').empty();
querySnapshot.forEach((doc) => {
const comment = doc.data();
let temp_html = `
<div class="col">
<div id=${doc.id} class="card border-light mb-3" style="max-width: 100rem" data-password="${comment.Password}">
<div class="card-body">
<h5 class="card-title">${comment.name}</h5>
<p class="card-text">${comment.comment}</p>
<button type="button" class="btn btn-outline-primary edit-btn">수정</button>
<button type="button" class="btn btn-primary delete-btn">삭제</button>
</div>
</div>
</div>`;
$('#card').append(temp_html);
});
}
window.onload = async function () {
await renderComments();
};
$('#makeComment').click(async function () {
let name = $('#name').val();
let Password = $('#Password').val();
let comment = $('#comment').val();
let doc = {
name: name,
Password: Password,
comment: comment,
};
const docRef = await addDoc(collection(db, 'storyCard1'), doc);
alert('저장 완료!');
window.location.reload();
});
addDoc으로 생성되는 Comment창에 동시에 doc에 생성되는 무작위 ID를 부여한다.
그리고 getDoc으로 불러와서 생성한다. 그렇게 되면 생성된 댓글창은 무작위로 생성되었지만 각각의 고유한 ID를 가지게 된다.
그런데 이렇게 ID를 부여한 것은 좋은데, 이 ID를 불러오는 과정 또한 쉽지 않았다.
// 삭제기능 //
$(document).on('click', '#card .delete-btn', function () {
const deleteBtn = $(this);
const cardBody = deleteBtn.closest('.card-body');
const passwordControls = cardBody.find('.password-controls');
if (passwordControls.length === 0) {
const passwordControlsHTML = `
<div class="password-controls">
<input type="password" class="form-control password-input" placeholder="Password">
<button type="button" class="btn double-check-btn" >비밀번호 확인</button>
</div>`;
cardBody.append(passwordControlsHTML);
} else {
passwordControls.show();
}
});
$(document).on('click', '#card .password-controls .double-check-btn', async function () {
const doubleCheckBtn = $(this);
const docId = doubleCheckBtn.closest('.card')[0].id;
const cardBody = doubleCheckBtn.closest('.card-body');
const enteredPassword = cardBody.find('.password-input').val();
const storedPassword = cardBody.closest('.card').data('password');
if (enteredPassword === String(storedPassword)) {
const askConfirm = confirm('정말 삭제 하시겠습니까?');
if (askConfirm) {
await deleteDoc(doc(db, 'storyCard1', docId));
doubleCheckBtn.closest('.col').remove();
}
} else {
alert('비밀번호가 틀립니다.');
}
// 입력창 제거
cardBody.find('.password-controls').hide();
});
먼저 해당 코드의 comment 삭제 매커니즘에 대해서 정확한 파악이 필요하다.
comment를 작성하면, comment창과 함께 내부에 수정, 삭제 버튼이 생성된다.
-> 이때, 삭제 버튼을 누르게되면 text를 입력 할 수 있는 창과 비밀번호 확인 창을 생성한다
-> comment 생성시 입력했던 Password를 입력후 비밀번호 확인 버튼을 누르게 된다면,
-> Password의 일치여부를 확인하고 최종적으로 comment를 삭제한다.
따라서 이 comment의 삭제 기능은 최종적으로 비밀번호 확인 버튼 즉 'double-check-btn' 에 넣고싶었다.
$(document).on('click', '#card .password-controls .double-check-btn', async function () {
const doubleCheckBtn = $(this);
const docId = doubleCheckBtn.closest('.card')[0].id;
closest() 메서드는 자신에게서 가장 가까운 정보를 찾는 이다. 따라서, 가장 가까운 .card를 출력하는 것이다.
그런데, 이 코드를 해석하면
docId 를 선언하는데 이것은 즉 doubleCheckBtn에서 가장 가까운 card중 첫번째 의 ID를 말하게 된다.
(comment가 많으면 여러 ID가 존재하겠지만, closest로 가장 가까운 부모의 ID를 따라가게 된다.)
이 부분을 이해하는데 굉장히 오랜 시간이 걸렸는데, 확실히 Jquery객체를 다지면서 다시 한 번 더 확인해보아야 하는 포인트임을 느낀다.
따라서 첫번째에 해당하는 가장 가까운 ID는 처음 addDoc을 통해 firebase의 DB에 저장된 doc의 ID를 가지게 된다.
await deleteDoc(doc(db, 'storyCard1', docId));
삭제를 위해 한 deleteDoc 코드를 작성한다.
storyCard1 이라는 collection내부의 db에 존재하는 'docID' 값을 삭제한다.
이렇게 삭제의 매커니즘을 구현하니 수정은 더욱 쉬웠다. 수정은 updateDoc를 이용했다.
// 수정 기능
$(document).on('click', '#card .edit-btn', function () {
const card = $(this).closest('.card');
const docId = card[0].id;
마찬가지로 click 이벤트로 생성된 수정버튼에서, card의 첫번째 id 즉 위에서 부여한 docId를 다시 호출하고 선언하게 된다.
당연한 이유이지만, 재선언한 이유는 전역선언이 아니기 때문에 그렇다.
이미 생성된 Card가 고유한 ID를 가지고 있으므로 그것을 호출,
마찬가지로 modifycomment라는 변수로 선언, 해당 변수를 업데이트 하는데 name과 comment를 각각
수정된 이름(title이라는 변수를 이름 작성란으로 사용하였다.)
수정된 코멘트에 부여하여 updateDoc기능을 사용했다.
이렇게 길었던 고민의 시간을 가지니, 배열에서 고민했던 부분이 사실 ID 할당이었던 것을 생각해보면
처음부터 Jquery와 Javascript를 확실히 다져두는게 얼마나 도움이 되는지 이 부분을 절실히 느꼈다.
'JavaScript' 카테고리의 다른 글
2024.1.2 기록 (this와 call 그리고 apply) (2) | 2024.01.02 |
---|---|
2023.12.29 기록 (Javascript 환경에서 API key를 github으로 유출하지 않는 방법) (2) | 2023.12.29 |
2023.12.27 기록 (foreach와 map, 그리고 firebase) (1) | 2023.12.27 |
2023.12.26 기록 (firebase hosting) (0) | 2023.12.26 |
2023.12.25 기록 ( callback, promise, async, await) (0) | 2023.12.25 |