video detail
videoRouter.get("/:id", watch);
videoRouter.route("/:id/edit").get(getEdit).post(postEdit);
videoRouter.route("/upload").get(getUpload).post(postUpload);
이렇게 동작하면 /upload 도 /:id중 하나라고 인식하여 watch가 렌더링됨
두가지방법
1.upload를 윗줄에
videoRouter.route("/upload").get(getUpload).post(postUpload);
videoRouter.get("/:id", watch);
videoRouter.route("/:id/edit").get(getEdit).post(postEdit);
2.정규표현식으로 0부터9또는 a부터f인 24개 찾아서(몽구스가 임의로 정한 아이디 형식) watch렌더링하기
hexadecimal regular expression
videoRouter.get("/:id([0-9a-f]{24})", watch);
videoRouter.route("/:id([0-9a-f]{24})/edit").get(getEdit).post(postEdit);
videoRouter.route("/upload").get(getUpload).post(postUpload);
정규표현식
http://regexpal.com
몽고DB Document
몽고DB는 ObjectID를 24바이트 16진 문자열 표현으로 반환한다.
https://mongodb.github.io/node-mongodb-native/api-bson-generated/objectid.html
https://docs.mongodb.com/manual/reference/method/ObjectId/
ObjectID()
Constructor
Create a new ObjectID instance
class ObjectID()Arguments:Returns:
- id (string) – Can be a 24 byte hex string, 12 byte binary string or a Number.
object instance of ObjectID.
십육진법 (Hexadecimal)
십육진법은 십육을 밑으로 하는 기수법이다. 보통 0부터 9까지의 수와 A에서 F까지의 로마 문자를 사용하고, 이때 대소문자는 구별하지 않는다.
Hexadecimal: 0~9까지의 숫자와 A-F까지의 알파벳이 조합된 string
+정규식 연습할 수 있는 사이트 https://regex101.com/
정규식에 대한 MDN의 공식 문서 https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Regular_Expressions
위에 라우터를 설정해도 watch가 렌더링 되지 않는데
watch.pug코드
extends base.pug
block content
p=video.dsecription
small=video.createdAt
a(href=`${video.id}/edit`) Edit video →
에러 --> video가 정의되지않음
videoController코드
export const watch = (req, res) => {
const { id } = req.params; // id가 있다 -->비디오를 찾을 수있다.
return res.render("watch", { pageTitle: `Watching` });
}
export const watch = async (req, res) => {
const { id } = req.params; //express가 주는 기능 Router주소
const video = await Video.findById(id); // mongoose quries중 하나 해당 아이디를 가진 모델 찾아주는 기능 console.log(video); // 비디오가 콘솔창에나온다면 지우고
return res.render("watch", { pageTitle: video.title, video });//watch 템플릿에 비디오 전달해주기
}
-------------------------------------------------------------------------------------------------------------------------------
post edit 코드
export const postEdit = async (req, res) => {
const { id } = req.params;
const { title, description, hashtags } = req.body;
const video =await Video.findById(id); //데이터베이스에서 검색한 영상 object 자체가져오기
if (!video) {
return res.render("404", { pageTitle: "Video not found" })
}
video.title = title; ///object 속성 고치기
video.description = description;
video.hashtags = hashtags
.split(",")
.map((word) => (word.startWith("#") ? word : `#${word}`));
await video.save();
return res.redirect(`/videos/${id}`);
}
코드 깔끔하게 만들기
Model.exist() //ture,false 반환 위와 달리post Edit 할 때 object전체 안가져와도됨 , id를 받지않고 filter받음(조건검색)
Model.findById AndUpdate() 이용해서
export const postEdit = async (req, res) => {
const { id } = req.params;
const { title, description, hashtags } = req.body;
const video = await Video.exists({_id : id}); //true
if (!video) {
return res.render("404", { pageTitle: "Video not found" })
}
await Video.findByIdAndUpdate(id,{
title,
description,
hashtags: hashtags
.split(",")
.map((word) => (word.startWith("#") ? word : `#${word}`)),
})
return res.redirect(`/videos/${id}`);
}
그렇다면 다음 getEdit function 도 위같이 사용 할 수있는가?
--> 아님
export const getEdit = async (req, res) => {
const { id } = req.params;
const video = await Video.findById(id);
if (!video) {
return res.render("404", { pageTitle: "Video not found" })
}
return res.render("edit", { pageTitle: `Edit ${video.title} `, video }); ///video Object를 템플릿에 보내줘야하기 때문에
}