RECAP - WETUBE

watch, edit handler

taehyeki 2021. 9. 23. 21:44

watch pug를 만들어 우리가 제목을 클릭하면 그 내용을 볼 수 있도록 만들어 줍니다.

render에서 video라는 객체를 보내주어 title, description, createAt을 나타내줍니다.

자 그럼 handler로 넘어가볼까요?

 

id를 params를 통해 가져오고 

await Video.findById(id)를 하여 딱 맞는 데이터를 가져옵니다. 

공식 문서에는

Video.findById(id).exec();

뒤에 exec를 붙이라고 나와있는데 딱히 붙이지 않아도 상관은 없다. 붙이면 어떻게 될까?

promise객체를 반환한다. 근데 ??

await을 쓸려면 Promise를 대상으로만 작동이 되기에 Promise이어야 합니다

예를들어 setTimeout은 Promise반환을 하지 않기 때문에 async와 await를 적용해도 동기적으로 적용되지 않는다고 한다. 따라서 Promise를 반환하게 직접 작성 후 async와 await를 적용해야한다고 한다.

 

findById().exec()는 promise를 반환하는데 find({})자체는(find에는 exec안씀) promise를 반환하는것같지는 않으면서도 then은 사용가능하다...? 또한 await를 쓸 수 있는 걸로 봐서 암튼 promise를 반환하는듯하다..

 

!! await 안썼을 경우  
  const a = Video.findById(videos[0].id); 
  const b = Video.findById(videos[0].id).exec();
a는 쿼리를반환
b는 promise pending을 반환( 이유는 await을 해주지 않아서 return이 된 후에 값을 찾아오기때문 await 해주면 잘 나옴)
무튼 exec를 하나 안하나 await가 작동되는 걸로 보아 promise를 둘다 반환하는듯? 좀더 공부해보자 ㅠㅠ

 

아무튼 중요한건 아니고!!

if 문을 사용해서 database를 못찾았을때를 구별해주자!!

 

router에 가서도 id에 대한 설정을 해주어야한다.

mongo는 앞서 말했다 싶이 자동으로 _id라는 고유 값을 생성해주는데 

16진수로 이루어져있고 24자로 이루어져있다. 따라서 그에 맞는 정규식을 통해 구별해낼수 있다.

이렇게 해주면 된다.

 

그리고 home 화면에서 목록을 클릭할 수 있도록 a태그로 만들어 주었다.

여기서 중요한 점이. 상대경로 절대경로이다.

pug를 render하는 url이 예를들어 현재 video/edit 이라면 
pug에서 a(href="see) 이렇게 하면 localhost:4000/video/see로 상대url이 생성되고
pug에서 a(href="/see) 이렇게 하면 localhost:4000/see로 절대url이 생성된다 .

 

그리고 video.id로 하면 신기하게도 string값으로 잘 나오기때문에 저렇게 해주었다.

video._id로 받으면 object반환

 

이번에는 edit파일을 만들어 줄것이다.

edit을 통하여 video의 제목, 내용 등을 수정할 수 있도록 한다.

그러려면 getEdit과 postEdit으로 나누어 주어야 할 것이다.

 

getEdit

url에서 가져올 수 있는 id를 통해 video를 찾아서 렌더링해준다.

value값에 직접 값을 넣어줌으로써 이전에 적어두었던 값들이 나오도록 한다.

textarea에서는 value에 넣으면 나오지 않아서 내용에 적어두었다.

배열에서 만약 video.hashtags만 적으면 배열상태로 출력이 된다. 따라서 join()함수를 통하여 text로 변환시켜주었다.

 

여기서 만약 아무 변경사항 없이 Upload Video 버튼을 누르면 어떻게 될까?

아무 변경사항이 생기지 않을까?? hashtags들이 앞에 #하나가 더 붙을 것이다. 우리는 여기서 앞에 #있는 경우와 없는 경우또한 생각해줘야한다. 

 

postEdit

Video.exists({})는 중괄호 안에 특정 조건을 넣어서 그에 해당하는 데이터가 있는지 없는지 true,false로  출력이 된다.

우리는 여기서 video값을 가져와서 뭘 하는것이 없으므로 존재여부만 확인하면 될것같아 findById를 사용하지 않았다.

 

여기서 변경된사항을 req.body에 담아와서 Video.indByIdAndUpdate(id,{}) 를 사용하여 업데이트를 해준다.

video.title : title 이런식으로 일일이 수동으로 업데이트 한뒤 video.save()를 해줄 수 도 있지만 form의  input이 수백개라면 후덜덜 할것이다. 따라서 간편한 방법을 사용해보았다.

 

hashtags: Video.formatHashtags(hashtags)를 사용하여 앞서 말한 #의 문제점을 해결하였다. 

Video.js

videoSchema의 설정을 조금 변경해주었다. static으로 함수를 만들면 Vido.find처럼 Video로 바로 호출할 수 있다.

startsWith는 시작하는 문자열이 있으면 true, false로 나오므로 삼항연산자를 이용하여 간단히 #의 유무를 확인할 수 있다. 앞서 우리가 videoEdit.pug에서 hashtags.join()을 해주었기 때문에 !! 문자열로 나온다. split으로 다시 배열로 만들어 준다.

 

여기서 videoSchema.pre('save', async () => { this.hashtags = this.hashtags~~~}) 이걸 사용하면 저장이 되기전에 실행되는 미들웨어를 만들 수 있다. 여기선 this.hashtages[0]로 해주어야한다. 저장 직전이라 배열 상태이기 때문이다. 

하지만 이건 findByIdAndUpdate일때는 save hook을 사용할 수 없기 때문에 생성될때와 수정될 때 모두 사용할 수 있도록 함수를 만들어 준 것이다.