본문 바로가기
Databases/To Do List DB

[ToDoList DB 6] 데이터 삭제- 해당 페이지에 있는 데이터 삭제

by CodeMia 2021. 11. 27.

지금까지의 코드로는 해당 페이지에서 아이템을 지우면 

메인인 "Today"로 이동만 되고 막상 해당 아이템은 지워지지 않는다.

 

cleaning rooms를 체크박스에 체크해서 지웠는데, 

 

 

바로 "Today" 화면으로 이동을 해버린다.

 

 

근데 다시 home으로 돌아가면 그 아이템은 지워지지 않고 아직 살아있다.

 

 

 

 

 

이 문제를 해결해 보자. 

list.ejs에서 delete가 일어나는 form은 다음과 같다. 

list.ejs

method="post" post request를

action="/delete"  /delete route로 보내고 input에 설정된 내용을 전달pass over한다. 

value:"<%= item._id%>" 는 유저가 지우기를 원하는 아이템의 id이고

onChange="this.form.submit() "  체크박스는 submit 버튼이 없어서 대신 

체크박스를 체크하면 form이 서버로 보내진다. 

 

 

 

 

app.js의 delete route에서 우리는 그냥 item 만을 찾도록 설정되어 있다. 

이 것을 좀 더 구체적으로 어떤 리스트에서의 item을 지워야 하는지는 나와있지 않다. 

app.js

line 106:  체크 박스의 id를 저장 

 

 

어떤 리스트에서의 아이템인지를 알아보자. 

지금의 인풋 list.ejs 안 line 13번 

<input type="checkbox" name="checkbox" value="<%= item._id %>" onChange="this.form.submit()">

list.ejs에서 체크박스 form이 submit 될 때

name과 value도 같이 submit 된다.

여기에서는

name이 체크 박스와 value는 할 일(item)의 id 이 2가지를 보낼 수 있다. 

 

하지만 어떤 리스트 이름인지는 보낼 수없다. 

여기서 리스트 이름도 서버로 보내려면 어떻게 해야할까?

 

문제는 이 체크 박스 form에는 checkbox 말고 다른 input이 없고 

이미 name, value를 사용하고 있어 list 이름을 담을 곳을 없다. 

 

 

이런 경우 input을 하나 더 집어 넣을 수 있다. 

<input type= "hidden"></input> 을 따로 만들어 사용할 수 있다. 

 

 


 

https://www.w3schools.com/tags/att_input_type_hidden.asp

hidden field는

form이 submit 될 때 유저가 편집하거나 보여지지 않는 데이터를 담고 있다. 

form이 submit 될 때 업데이트 되어야할 데이터베이스 기록을 자주 담고 있다. 

유저도 browser's developer tools나 "View Source"에서는 볼 수 있음으로 보안이 되는 건 아니다. 

 

 


 

지금의 경우에는 <input type= "hidden"></input> 으로  list 이름을 보낼 것이다. 

 

checkbox input이 끝나는 div 아래에 

<input type= "hidden"></input>을 입력해준다. 

name과 value를 각각 설정해서 delete route로 보내준다. 

 

 

 

listName으로 변수를 만든다.

만약 listName이 "Today"이면 원래 있던 코드를 if 안으로 넣어서 실행되도록 했다. 

 

 

so that delete request is actually coming from a custom list.

in this case we need to be able to find the list document

that has the current listName

and then we need to update that list to remove the checked item with that particular ID. 

Now because inside our list document there's an array of item documents 

then it's actually a little bit more complex bz we basically have to find an item 

inside this array. 

 

이제는 list Name을 찾아야 한다. 

ltems array 안을 일일이 하나하나 

else인 경우  items array 안에서 원하는 listName을 찾고, 

체크된 아이템의 특정 id를 찾아서 지워야한다.

이 때 for loop과 js filter method를 사용하여 하나씩 확인해서

찾을 수 있긴 하지만 더 간단한 방법이 있다. 

 

 

mongoose에서 array안 document를 지우고 나서 저장까지 하려면  $pull, $pullAll 을 사용하라고 나온다.

 

 


$ pull

https://docs.mongodb.com/manual/reference/operator/update/pull/

 

 

 

Mongoose findOneAndUpdate() syntax

findOneAndUpdate()은 3개의 파라미터를 갖는다.

1. condition: 찾고자 하는 것 

2. update: 업데이트 하고 싶은 것 

3. function: 콜백 

 

 

2번 째 파라미터인 update를 조금 더 잘게 나눠서

{$pull: {field: {query}}} 로 써줄 수 있다.

$pull operator를 key로 사용하고,

value는 an array of items 이다.

and then we have to provide a value for that field,

which item in that array of items. 

 

 

 

 

 


그럼 findOneAndUpdate()를  else 자리에 넣어보자.

 

1단계

 

2단계 

 

3단계 

 

 

 

 

결과 보기 

 

 

cleaning rooms를 체크하면 지워지고 home에도 그대로 머물러 있다. 

 

 

 

 

 

 

댓글