const ctx = document.getElementById("myChart");
let chart = new Chart(ctx, {
type: "bar",
data: {
labels: nameArr,
datasets: [
{
data: dataIdArr,
backgroundColor: [
`rgba(${randomNum()}, ${randomNum()}, ${randomNum()}, 0.3)`,
`rgba(${randomNum()}, ${randomNum()}, ${randomNum()}, 0.3)`,
`rgba(${randomNum()}, ${randomNum()}, ${randomNum()}, 0.3)`,
`rgba(${randomNum()}, ${randomNum()}, ${randomNum()}, 0.3)`,
`rgba(${randomNum()}, ${randomNum()}, ${randomNum()}, 0.3)`,
],
borderWidth: 1,
},
],
},
options: {
...
},
});
// firestore에서 데이터를 받아와 배열을 생성하는 부분.
const getLikes = async () => {
const likesData = await getDocs(query(likeRef, orderBy("order", "asc")));
nameArr = [];
likeArr = [];
dataIdArr = [];
// chart에 필요한 data array
likesData.forEach(data => {
const getData = data.data();
dataIdArr.push(data.id);
nameArr.push(getData.name);
likeArr.push(getData.like);
});
};
// 좋아요 버튼
const likeBtns = document.querySelectorAll(".member-section__like-card");
likeBtns.forEach((btn, index) => {
btn.addEventListener("click", async event => {
event.preventDefault();
const currentLikeId = dataIdArr[index];
const getLike = await getDoc(doc(db, "member_like", currentLikeId));
likeObj.name = getLike.data().name;
likeObj.like = getLike.data().like + 1;
likeObj.order = getLike.data().order;
await setDoc(doc(likeRef, currentLikeId), likeObj).then(async () => {
chart.data.datasets[0].data = getLikes();
chart.update();
});
});
});
차트를 생성할 div를 불러와 차트 생성자 인수로 넘기면 차트가 생성된다.
이때 필요한 labels
의 데이터와 data
의 데이터를 firestore에서 불러와 배열 nameArr
, dataIdArr
을 만들어 넣어 주고 차트를 생성한다.
getLikes()
함수를 호출하면 firestore
에서 받아온 데이터를 각 전역 배열 변수에 필요한 데이터를 push
하여 배열을 완성시킨다.
완성된 전역 배열 변수를 참조하여 차트가 생성된다.
위에 작성된 코드는 좋아요 버튼 이벤트에서 getLikes()
함수를 호출하고 그 후 chart.update()
메서드를 사용해 차트를 업데이트를 하면 아무 반응이 없었다.
작성중에도 완벽히 이해하진 못 했지만 이해한대로 작성해보자면 getLikes()
는 async
함수이지만 chart.update()
는 일반 메서드라서 실행 순서가 꼬여서 문제가 생기는 같다.
이를 해결하기위해 버튼 이벤트에서 getLikes()
를 바로 호출하는게 아닌 await getLikes()
로 호출하여 비동기 처리가 수행될 때까지 기다렸다가 다음 라인 코드를 실행하게 바꾸었다.
// 차트 생성
let chart = new Chart(ctx, {
type: "bar",
data: {
labels: nameArr,
datasets: [
{
data: await getLikes(),
backgroundColor: [
`rgba(${randomNum()}, ${randomNum()}, ${randomNum()})`,
`rgba(${randomNum()}, ${randomNum()}, ${randomNum()})`,
`rgba(${randomNum()}, ${randomNum()}, ${randomNum()})`,
`rgba(${randomNum()}, ${randomNum()}, ${randomNum()})`,
`rgba(${randomNum()}, ${randomNum()}, ${randomNum()})`,
],
borderWidth: 1,
borderRadius: 100,
barThickness: 50,
},
],
},
options: {
...
},
});
// firestore에서 데이터를 받아와 배열을 생성하는 부분.
const getLikes = async () => {
const likesData = await getDocs(query(likeRef, orderBy("order", "asc")));
nameArr = [];
let likeArr = [];
dataIdArr = [];
// chart에 필요한 data array
likesData.forEach(data => {
const getData = data.data();
dataIdArr.push(data.id);
nameArr.push(getData.name);
likeArr.push(getData.like);
});
return likeArr;
};
// 좋아요 버튼
const likeBtns = document.querySelectorAll(".member-section__like-card");
likeBtns.forEach((btn, index) => {
btn.addEventListener("click", async event => {
event.preventDefault();
const currentLikeId = dataIdArr[index];
const getLike = await getDoc(doc(db, "member_like", currentLikeId));
likeObj.name = getLike.data().name;
likeObj.like = getLike.data().like + 1;
likeObj.order = getLike.data().order;
await setDoc(doc(likeRef, currentLikeId), likeObj).then(async () => {
chart.data.datasets[0].data = await getLikes();
chart.update();
});
});
});
위 코드와 같이 getLikes()
를 호출하는 부분에 await
키워드를 사용하여 비동기 호출 시 비동기가 처리가되면 다음 코드로 진행되게 바꾸어 해결하였다.
Promise의 이해
Promise 부분을 javascript 딥다이브 책에서 한번 읽었지만 완전히 이해를 하진 못하고 있다. 비동기 부분은 실행순서가 일반적인 코드와 다르다 보니 완벽히 이해를 해야겠다는 생각을 절실히 느끼는 기능이었다. 한번으로는 부족했으니 두번 세번 이해가 될때까지 읽고 실습을 해야겠다.
공부에는 지름길은 없다.
책을 읽고 이해하고, 반복숙달 하자! 할 수 있다!!!!!!