# 댓글 등록 with 자바스크립트(JS)
## 미션
댓글 등록 페이지를 만들고, REST API를 호출하여 새 댓글을 추가하시오.
![홍팍-스프링-부트-입문--미션](http://drive.google.com/thumbnail?export=view&sz=w960&id=1eFFS_SXBiPZ3tTYmHHXKmSw5l2c3zZlD)
## 01:56 댓글 생성 뷰 페이지 - 부트스트랩 Card, Form
#### ../comments/_new.mustache
```
<div class="card m-2" id="comments-new">
<div class="card-body">
<!-- 댓글 작성 폼-->
<form>
<!-- 닉네임 입력 -->
<div class="mb-3">
<label class="form-label">닉네임</label>
<input type="text" class="form-control form-control-sm" id="new-comment-nickname">
</div>
<!-- 댓글 본문 입력 -->
<div class="mb-3">
<label class="form-label">댓글 내용</label>
<textarea type="text" class="form-control form-control-sm" rows="3" id="new-comment-body"></textarea>
</div>
<!-- 히든 인풋 -->
{{#article}}
<input type="hidden" id="new-comment-article-id" value="{{id}}">
{{/article}}
<!-- 전송 버튼 -->
<button type="button" class="btn btn-outline-primary btn-sm" id="comment-create-btn">댓글 작성</button>
</form>
</div>
</div>
```
## 05:34 버튼 클릭 이벤트 감지
#### ../comments/_new.mustache
```
<div class="card m-2" id="comments-new">
...
</div>
<Script>
{
// 댓글 생성 버튼 변수화
const commentCreateBtn = document.querySelector("#comment-create-btn");
// 댓글 클릭 이벤트 감지!
commentCreateBtn.addEventListener("click", function() {
console.log("버튼이 클릭 되었습니다.");
});
}
</script>
```
## 11:03 새 댓글 JS 객체 생성 - JS 객체 리터럴
#### ../comments/_new.mustache
```
<div class="card m-2" id="comments-new">
...
</div>
<Script>
{
// 댓글 생성 버튼 변수화
const commentCreateBtn = document.querySelector("#comment-create-btn");
// 댓글 클릭 이벤트 감지!
commentCreateBtn.addEventListener("click", function() {
// 새 댓글 객체 생성
const comment = {
nickname: document.querySelector("#new-comment-nickname").value,
body: document.querySelector("#new-comment-body").value,
articleId: document.querySelector("#new-comment-article-id").value
};
// 댓글 객체 출력
console.log(comment);
});
}
</script>
```
## 15:34 자바스크립트 REST API 호출 - fetch()
#### ../comments/_new.mustache
```
<div class="card m-2" id="comments-new">
...
</div>
<Script>
{
// 댓글 생성 버튼 변수화
const commentCreateBtn = document.querySelector("#comment-create-btn");
// 댓글 클릭 이벤트 감지!
commentCreateBtn.addEventListener("click", function() {
// 새 댓글 객체 생성
const comment = {
nickname: document.querySelector("#new-comment-nickname").value,
body: document.querySelector("#new-comment-body").value,
article_id: document.querySelector("#new-comment-article-id").value
};
// 댓글 객체 출력
console.log(comment);
// fetch() - 비동기 통신을 위한 API
const url = "/api/articles/" + comment.article_id + "/comments";
fetch(url, {
method: "post",
body: JSON.stringify(comment),
headers: {
"Content-Type": "application/json"
}
});
});
}
</script>
```
## 22:40 fetch() 응답 처리 - response.ok, alert(), window.location.reload()
#### fetch 응답 결과로 화면 바꾸기 - comments/_new.mustache
```
<div class="card m-2" id="comments-new">
...
</div>
<Script>
{
// 댓글 생성 버튼 변수화
const commentCreateBtn = document.querySelector("#comment-create-btn");
// 댓글 클릭 이벤트 감지!
commentCreateBtn.addEventListener("click", function() {
// 새 댓글 객체 생성
const comment = {
nickname: document.querySelector("#new-comment-nickname").value,
body: document.querySelector("#new-comment-body").value,
article_id: document.querySelector("#new-comment-article-id").value
};
// 댓글 객체 출력
console.log(comment);
// fetch() - 비동기 통신을 위한 API
const url = "/api/articles/" + comment.article_id + "/comments";
fetch(url, {
method: "post",
body: JSON.stringify(comment),
headers: {
"Content-Type": "application/json"
}
}).then(response => {
// http 응답 코드에 따른 메시지 출력
const msg = (response.ok) ? "댓글이 등록되었습니다." : "댓글 등록 실패..!";
alert(msg);
// 현재 페이지 새로고침
window.location.reload();
});
});
}
</script>
```
## 🔥 구글링 훈련하기
- 부트스트랩5 Card
- 부트스트랩5 Form
- HTML form input hidden
- JavaScript addEventListener 클릭
- JavaScript querySelector 사용법
- JavaScript 객체 리터럴
- JavaScript console log
- JavaScript fetch
- JavaScript alert
- JavaScript location reload