간단한 미니 방명록 페이지에서 좋아요 버튼을 누르면 좋아요가 카운트되도록 하는 기능을 구현하는 과정,

GET 을 이용해서 HTML에 뿌려줄때 _id값도 함께 가져오도록 하였는데 계속해서 오류가 발생했다.
찾아보니 자바스크립트에서는 ObjectId자료형을 사용할 수 없다고 한다.
어쩔 수 없이 문자열 형태로 내보내도록 코드를 수정했다.
@app.route("/guestbook", methods=["GET"])
def guestbook_get(): # 코멘트를 가져오는 부분
all_comments = list(db.fan.find())
for comment in all_comments:
comment['_id'] = str(comment['_id']) # ObjectId를 str 형태로 변환합니다.
return dumps({'result': all_comments})
넘겨받은 값을 시각화하기 위해 코드를 살짝 수정하고 id값을 넘겨 받도록 작성했다.
function show_comment() {
fetch('/guestbook').then((res) => res.json()).then((data) => {
let rows = data['result']
$('#comment-list').empty()
rows.forEach((a) => {
let id = a['_id']
let name = a['name']
let comment = a['comment']
let likes = a['likes']
// console(id)
let temp_html = `<div class="card">
<div class="card-body">
<blockquote class="blockquote mb-0">
<p>${comment}</p>
<footer class="blockquote-footer">${name}</footer>
<p>${id}</p>
<p style="text-align:right"><button class="btn btn-primary" type="submit" onclick="add_like(${id})"> ${likes} like</button></p>
</blockquote>
</div>
</div>`
$('#comment-list').append(temp_html)
});
})
}
자료형 문제라는 것을 깨닳는데 시간이 많이 소요되었다. POST 매서드의 문제라고 생각해서 전혀 엉뚱한 문제를 찾느라 해결책을 전혀 발견하지 못했었다.
이제 버튼을 누르면 like 값이 1씩 증가하도록 기능을 구현하는 일이 남았다.
버튼을 누른 코멘트에만 like가 증가해야하므로 아까 넘겨 받도록 설정한 id를 매개변수로 받는 함수를 작성했다.
script
function add_like(id) {
let formData = new FormData();
formData.append("search_id_give", id);
fetch('/add_like', { method: "POST", body: formData, }).then((res) => res.json()).then((data) => {
});
}
Python Flask
@app.route('/add_like', methods=['POST'])
def like_post(): # 좋아요 버튼을 누르면 해당 게시물의 좋아요 값이 1씩 더해지는 코드
search_id_receive = request.form['search_id_give']
db.fan.update_one({'_id': ObjectId(search_id_receive)}, {'$inc': {'likes': 1}})
return jsonify({'result':'success', 'msg': '이 요청은 POST!'})
내 기대와 달리 기능이 동작하지 않았다.
Chrome의 Console 창을 확인하니 아래와 같은 오류 문구가 표시되고 있었다.

찾아보니 자바스크립트 문법 오류라고 한다.
어디서 문제를 찾아야할지 막막해 숨이 턱 막히고 말았다.
이 문제로 이곳 저곳에 물어보고 도움을 요청한 결과 의외로 해법은 생각보다 간단했다. 수정한 코드는 다음과 같다.
<button class="btn btn-primary" type="submit" onclick="add_like('${id}')"> ${likes} like</button>
temp_html 안에서 id변수를 가져올 때 값을 str 형태로 가져오는 것으로 해결할 수 있었다.
최종적으로 이러한 코드가 완성된다.
Python Flask
@app.route('/add_like', methods=['POST'])
def add_like_post():
search_id_receive = request.form['search_id_give']
db.fan.update_one({'_id': ObjectId(search_id_receive)}, {'$inc': {'likes': 1}})
return jsonify({'msg': '좋아요!를 했습니다.'})
script
function show_comment() {
fetch('/guestbook').then((res) => res.json()).then((data) => {
let rows = data['result']
$('#comment-list').empty()
rows.forEach((a) => {
let id = a['_id']
let name = a['name']
let comment = a['comment']
let likes = a['likes']
let temp_html = `<div class="card">
<div class="card-body">
<blockquote class="blockquote mb-0">
<p>${comment}</p>
<footer class="blockquote-footer">${name}</footer>
<p style="text-align:right"><button class="btn btn-primary" type="submit" onclick="add_like('${id}')">${likes} like</button></p>
</blockquote>
</div>
</div>`
$('#comment-list').append(temp_html)
});
})
}
function add_like(id) { /* 좋아요 기능 */
let formData = new FormData();
formData.append("search_id_give", id);
fetch("/add_like", { method: "POST", body: formData }).then(res => res.json()).then(data => {
window.location.reload()
})
}
ObjectId라는 자료형이 있다는 것도 처음 알게 되었다. 나는 이게 자료형인지도 모르고 그냥 보고 있었던 것이다. jSON은 ObjectId를 사용할 수 없기 때문에 str자료형으로 넘겨주어야하는 것, HTML TEMP를 활용할 때 필요한 경우 자료형을 확인해야하는 점을 확실하게 배웠다.
이 문제를 해결하려고 총 10시간을 찾아 헤메었는데 중간에 울기도 하고 마음이 부서질 것만 같았다. 문제를 해결할 수 있도록 도와준 수 많은 개발자들의 블로그, 그리고 코드를 함께 리뷰해주신 모든 분들께 감사하며 글을 마친다.
'Develop > TIL' 카테고리의 다른 글
자바스크립트 알고리즘 문제 풀이 주차 회고 (0) | 2023.04.21 |
---|---|
자바스크립트 입문 2주차 회고 (0) | 2023.04.13 |
자바스크립트 입문 1주차 회고 (0) | 2023.04.09 |
eb init no such file or directory 오류가 발생하는 문제 (0) | 2023.03.25 |
[Python] VS Code에서 imprort 문제가 생긴 경우 (0) | 2023.03.21 |