Youtube Clone Coding (14. video comment)

LeeJaeHoon·2021년 11월 13일
0
post-thumbnail
  1. Comment Model 만들기

    • comment는 만든사람이 한명밖에 존재 안한다.
    import mongoose from "mongoose";
    
    const commentSchema = new mongoose.Schema({
      text: { type: String, required: true },
      owner: { type: mongoose.Schema.Types.ObjectId, required: true, ref: "User" },
      video: { type: mongoose.Schema.Types.ObjectId, required: true, ref: "Video" },
      createAt: { type: Date, required: true, default: Date.now() },
    });
    
    const Comment = mongoose.model("Comment", commentSchema);
    
    export default Comment;
    • video는 comment가 여러개 존재 할 수 있다.
      const videoSchema = new mongoose.Schema({
        fileUrl: { type: String, required: true },
        thumbUrl: { type: String, required: true },
        title: { type: String, required: true, trim: true, maxlength: 80 },
        description: { type: String, required: true, trim: true, minlength: 10 },
        createdAt: { type: Date, required: true, default: Date.now },
        hashtags: [{ type: String, trim: true }],
        meta: {
          views: { type: Number, default: 0, required: true },
          rating: { type: Number, default: 0, required: true },
        },
        comments: [{ type: mongoose.Schema.Types.ObjectId, ref: "Comment" }],
        owner: { type: mongoose.Schema.Types.ObjectId, required: true, ref: "User" },
      });
    • user은 comment가 여러개 존재 할 수 있다.
      const userSchema = new mongoose.Schema({
        email: { type: String, required: true, unique: true },
        avatarUrl: { type: String },
        socialOnly: { type: Boolean, default: false },
        username: { type: String, required: true, unique: true },
        password: { type: String },
        name: { type: String, required: true },
        location: { type: String },
        videos: [{ type: mongoose.Schema.Types.ObjectId, ref: "Video" }],
        comments: [{ type: mongoose.Schema.Types.ObjectId, ref: "Comment" }],
      });
    • watch.pug에 comment에 대한 html만들기
      • 로그인한 유저만 댓글 달 수 있게 하기위해 조건문을 썼다.

        if loggedIn
              div.video__comments
                form.video__comment-form#commentForm
                  textarea(cols="30", rows="10", placeholder="공개 댓글 추가...")
                  button 댓글
  2. comment 백엔드에 보내기

    • fetch로 백엔드에 요청을 보낼 때
      • method → POST인지 GET인지 알려줘야함
      • headers → 요청의 세부 사항을 명시한다
        • headers 안에 "Content-Type": "application/json"이라는 명시를 해 주어 전송된 텍스트가 JSON파일임을 백엔드에 인식시켜 준다.
      • body → 백엔드에 보내줄 컨텐츠를 적는다
        • body: { ... }, 이런 식으로 자바스크립트 오브젝트를 넘겨줄 시 외부에서 이 오브젝트는 [object Object]라는 의미 없는 문자열로 변환된다. → 자바스크립트는 백엔드로 보낼때 문자열로 보내기때문!
        • JSON.stringify을 이용하여 JSON 문자열로 변환하여 보내주어야 한다.
    • 백엔드에서 json문자열을 자바스크립트 오브젝트로 변환해주기위해서는 다음과 같은 middleware을 써여한다.
      • app.use(express.json())
    const videoContainer = document.getElementById("videoContainer");
    const form = document.querySelector("#commentForm");
    
    const handleSubmit = e => {
      e.preventDefault();
      const textarea = form.querySelector("textarea");
      const text = textarea.value;
      const videoId = videoContainer.dataset.id;
      if (text === "") {
        return;
      }
      fetch(`/api/videos/${videoId}/comment`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          text,
        }),
      });
    };
    
    form.addEventListener("submit", handleSubmit);
    • comment controller
      • req.body를 통해 프론트에서 fetch로 보내준 내용을 얻을 수 있다.

        export const createComment = (req, res) => {
          console.log(req.body);
          return res.end();
        };
  3. 받은 comment로 comment create하기

    • status(201)은 create를 알려주는 상태코드이다.
    • sendStatus는 status code를 보내고 request를 끝내버린다.
      export const createComment = async (req, res) => {
        const {
          session: { user },
          body: { text },
          params: { id },
        } = req;
      
        const video = await Video.findById(id);
        if (!video) {
          return res.sendStatus(404);
        }
        const comment = await Comment.create({
          text,
          owner: user._id,
          video: id,
        });
        console.log(comment);
        return res.sendStatus(201);
      };
    • comment create하고 video에 comment push하기
      export const createComment = async (req, res) => {
        const {
          session: { user },
          body: { text },
          params: { id },
        } = req;
      
        const video = await Video.findById(id);
        if (!video) {
          return res.sendStatus(404);
        }
        const comment = await Comment.create({
          text,
          owner: user._id,
          video: id,
        });
        video.comments.push(comment._id);
        await video.save();
        return res.sendStatus(201);
      };
      • create한 comment 화면에 표시하기
        • reverse() 메서드는 배열의 순서를 반전한다. 첫 번째 요소는 마지막 요소가 되며 마지막 요소는 첫 번째 요소가 된다.

          div.video__comments 
                ul
                  each comment in video.comments.reverse()
                    li.video__comment=comment.text

0개의 댓글