댓글을 일반적인 post method 요청으로 추가할수도 있지만 AJAX로 구현하는 이유는 바로 페이지를 새로고침하는걸 보고싶지 않기 때문입니다. 이게 바로 AJAX의 포인트라고 할 수 있습니다.
youtube
  |views
   *|videoDetail.pug
 *|routes.js
  |routers
   *|apiRouter.js
  |controllers
   *|videoController.js
  |assets
    |js
     *|main.js
     +|addComment.js
videoDetail page에 댓글을 남길 수 있는 form을 추가해주겠습니다. form의 위치는 각자 원하는 위치에 넣어주면 됩니다.
form.video__add-comment#jsCommentForm
  input(type="text", placeholder="댓글 작성")
ul.video__comments#jsCommentList
  each comment in video.comments
    li #{comment.text}
const ADD_COMMENT = '/:id/comment';
const routes = {
  addComment: ADD_COMMENT;
}
export default routes;
import Comment from '../models/Comment';
export const postAddComment = async(req, res) => {
  const {
    params:{id},
    body:{comment},
    user
  }=req;
  
  try{
    const video = await Video.findById(id);
    const newComment = await Comment.create({
 	  text: comment,
      video: video.id,
      creator: user._id
    });
    video.comments.push(newComment.id);
    video.save();
    res.status(200);
  }catch(){
    res.status(400);
  }finally{
    res.end();
  }
}
export const videoDetail = async(req, res) => {
  /*생략했지만 try-catch문에 넣어주세요.*/
  const {params:{id}} = req;
  
  const video = await Video.findById(id)
    .populate("creator")
    .populate("comments");
  const comments = await Promise.all(video.comments.map(async comment => await Comment.findById(comment.id).populate('creator'));
  res.render("videoDetail", {video, commments});
  /*생략*/
}
import {postAddComment} from '../controllers/videoController';
apiRouter.post(routes.addComment, postAddComment);
%npm install axios를 터미널에 입력
axios는 fetch와 비슷한 역할을 하는데 아래와 같은 option을 객체로 전달하여 사용할 수 있다.
const commentForm = document.querySelector('#jsCommentForm');
const commentList = document.querySelector('#jsCommentList');
const addComment = (comment) => {
  const comment = document.createElement('li');
  comment.innerHTML = comment;
  //댓글이 최신순으로 위에 올라오길 원하면 appendChild가 아니라 prepend method를 사용하시면 됩니다.
  commentList.appendChild(comment);
}
async function handleAddComment (event){
  //페이지의 리로딩 방지
  event.preventDefault();
  const commentInput = commentForm.querySelector('input');
  const comment = commentInput.value;
  commentInput.value = '';
  const videoId = window.location.href.split("/videos/")[1];
  const response = await axios({
    url:`/api/${videoId}/comment`,
    method: "POST",
    data:{
      comment
    }
  });
  
  if(response.status === 200){
    addComment(comment);
  }
}
function init(){
  commentForm.addEventListener('submit', handleAddComment);
}
if(commentForm){
  init();
}
import './addComment.js';