본문 바로가기

카테고리 없음

nodejs랑 mongodb로 게시글 삭제 요청 해보기

반응형

이번엔 브라우저에서 nodejs 서버로 데이터 삭제 요청 해볼게요

db로도 데이터 삭제 요청 할거임

이 포스팅은 시리즈니깐 내용 이해 안되면

nodejs 게시판에서 이전 글 한번 보고 오세요

 

1. server.js

// express로 서버 만들기 기본 셋팅
const express = require("express");
const app = express();
const bodyParser = require('body-parser');
// bodyparser 사용 설정
app.use(bodyParser.urlencoded({extended: true}));

// ejs 사용 설정
app.set('view engine', 'ejs');

// 몽고DB랑 연결해주는 코드
const MongoClient = require('mongodb').MongoClient;
var db;
MongoClient.connect('mongodb+srv://bebsae:비밀번호@cluster0.kotmhwt.mongodb.net/?retryWrites=true&w=majority', 
function(에러, client){
    if(에러) {
        return console.log(에러)
    }
    // 나는 몽고db atlas에 todoapp이라는 이름의 데이터베이스를 만들어둠
    // 이 코드로 todoapp이라는 데이터베이스에 접속 가능
    db = client.db('todoapp');

    app.listen(8080, function(){
        console.log('db connected')
    })
})

/*
// listen(서버 띄울 포트번호, 띄운 후 실행할 코드)
app.listen(8080, function () {
    console.log("서버 실행 중");
});
*/

// get('경로', 함수)
// function(요청, 응답)
app.get("/first", function (req, res) {
    res.send("첫번째 페이지임");
});

app.get("/second", function (req, res) {
    res.send("두번째 페이지임요");
});

// html파일 띄우는 소스
app.get("/", function (req, res) {
    res.sendFile(__dirname + "/main.html");
});

app.get("/write", function (req, res) {
    res.sendFile(__dirname + "/write.html");
});

// POST요청을 처리하는 소스
app.post("/add", function (req, res) {
    res.send('전송완료');
    console.log(req.body.title);
    console.log(req.body.date);
    var title = req.body.title;
    var date = req.body.date;

    // counter라는 collection에서 데이터 가져오는 코드
    // 게시물갯수 라는 이름의 데이터를 찾아서 가져옴
    db.collection('counter').findOne({name: '게시물갯수'}, function(에러, 결과){
        console.log(결과.totalPost)
        var 총게시물갯수 = 결과.totalPost;
        // 몽고db atlas에 post라는 collection도 만들었었음
        // db에 데이터 저장하는 코드임
        // 데이터 양식은 {키 : 밸류} 형태임
        // _id는 데이터의 인덱스값 같은거 적어주는거임
        db.collection('post').insertOne({_id : 총게시물갯수+1, 제목 : title, 날짜 : date}, function(에러, 결과){
            console.log('저장완료');
            // db의 값을 업데이트(수정)하는 코드
            // updateOne({수정할데이터},{$set : {수정값}},function(){})
            // $set이 update operator(연산자)임, 값을 바꿔줌
            // 연산자에는 $inc도 있음 이건 값을 더해줌
            db.collection('counter').updateOne({name:'게시물갯수'},{$inc : {totalPost:1}},function(에러, 결과){
                if(에러){
                    return console.log(에러)
                }
            });
        });
    });
});

// ejs파일 불러오는 코드
app.get('/list', function(req, res) {
    // post라는 collection에서 모든 데이터 꺼내오기
    db.collection('post').find().toArray(function(에러, 결과){
        console.log(에러);
        console.log(결과);
        // DB에서 가져온 데이터를 ejs파일에 넣어 줌
        // 데이터는 posts라는 변수에 넣어 줌
        res.render('list.ejs', {posts : 결과});
    });

});

app.delete('/delete', function(req, res){
    console.log(req.body);
    req.body._id = parseInt(req.body._id);
    db.collection('post').deleteOne(req.body, function(에러, 결과){
        console.log('삭제 완료');
        // 성공 시 200번(성공) 응답 보냄
        // 실패 시 400번(실패) 응답 보냄
        // send 옵션으로 메시지도 보낼 수 있음
        res.status(200).send({message: '성공했습니다'});
        //res.status(400).send({message: '실패했습니다'});
    });
});

우선 server.js파일의 전체코드임

 

그 중에서도

app.delete('/delete', function(req, res){
    console.log(req.body);
    req.body._id = parseInt(req.body._id);
    db.collection('post').deleteOne(req.body, function(에러, 결과){
        console.log('삭제 완료');
        // 성공 시 200번(성공) 응답 보냄
        // 실패 시 400번(실패) 응답 보냄
        // send 옵션으로 메시지도 보낼 수 있음
        res.status(200).send({message: '성공했습니다'});
        //res.status(400).send({message: '실패했습니다'});
    });
});

DB에 삭제 요청하는 코드는 이거임

만약에 /delete URL로 요청이 들어오면 뭔가 삭제를 시킬거임

뭘 삭제할거냐면...

그 내용은 req.body를 통해 브라우저에서 전달받은 데이터에 들어있음

 

parseInt(req.body._id)를 이용해서 웹으로부터 전달받은 데이터 중 _id값을 숫자(int)로 바꿔줌

숫자로 바꾼 값은 req.body._id에 저장함

이렇게 하면 브라우저에서 전달받은 _id값을 문자가 아니라 숫자로 전달할 수 있고

그래야 DB가 알아들음

 

그리고 deleteOne을 이용해서, req.body._id로 전달받은 id값을 가진 데이터를 삭제해줌

atlas 웹페이지에서 본 적 있는 이 _id값을 의미함

까먹은 사람을 위해 부연설명하자면

mongodb에 데이터 저장할때 각 데이터마다 저렇게 _id값이 주어짐

이게 고유 값이라서 각 데이터를 구분할 수 있게 도와줌

 

나는 7번 id를 가진 데이터를 삭제해야 하는데

막 암거나 삭제하면 안되니까 저렇게 고유값을 줘서

특정 데이터만 골라낼 수 있도록 하는 거임

 

삭제 성공하면 res.status(200).send({메시지내용})을 이용해서

브라우저로 성공 메시지를 보내줌

여기서 200이 뭐냐면 성공했다는 응답을 보내겠다는거임

저기서 status안에 들어있는 값을 400으로 바꾸면 실패했다는 응답을 보내는거임

 

2. list.ejs

<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">

    <title>Hello, world!</title>
  </head>
  <body>
    <h1 class="ml-2 my-3">할 일 리스트</h1>
      <ul class="list-group">
        <% for (var i = 0; i < posts.length ; i++){ %>
        <li class="list-group-item">
          <h4>글 번호 : <%= posts[i]._id %></h4>
          <h4>할 일 제목 : <%= posts[i].제목 %></h4>
          <h4>할 일 마감 날짜 : <%= posts[i].날짜 %></h4>
          <button class="delete" data-id="<%= posts[i]._id %>">삭제</button>
        </li>
        <% } %>
      </ul>

    <script
  src="https://code.jquery.com/jquery-3.6.3.js"
  integrity="sha256-nQLuAZGRRcILA+6dMBOvcRh5Pe310sBpanc6+QBmyVM="
  crossorigin="anonymous"></script>
    <script>
      $('.delete').click(function(e){
        // 내가 누른 요소의 data-id값을 '글번호'라는 변수에 저장
        // e.target은 지금 클릭한 것을 의미
        var 글번호 = e.target.dataset.id;
        // this는 지금 이벤트가 동작하는 곳을 의미
        var 지금누른거 = $(this);

        $.ajax({
          method : 'DELETE',
          url : '/delete',
          data : {_id : 글번호},
        }).done(function(결과){
          // 브라우저 콘솔에 뜸
          console.log('성공했음');
          // 지금 누른 버튼의 부모 태그를 찾아 줌
          // fadeOut으로 해당 태그 사라지게 함
          지금누른거.parent('li').fadeOut();
        }).fail(function(xhr, textStatus, errorThrown){
          console.log(xhr, textStatus, errorThrown);
        });
      });
    </script>

    <!-- Optional JavaScript; choose one of the two! -->

    <!-- Option 1: jQuery and Bootstrap Bundle (includes Popper) -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-Fy6S3B9q64WdZWQUiU+q4/2Lc9npb8tCaSX9FK7E8HnRr0Jz8D6OP9dO5Vg3Q9ct" crossorigin="anonymous"></script>

    <!-- Option 2: Separate Popper and Bootstrap JS -->
    <!--
    <script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.min.js" integrity="sha384-+sLIOodYLS7CIrQpBjl+C7nPvqq+FbNUBDunl/OZv93DB7Ln/533i8e/mZXLi/P+" crossorigin="anonymous"></script>
    -->
  </body>
</html>

이번엔 list.ejs파일의 전체 코드임

jquery 연결 코드가 기존이랑 바뀌었으니 참고하시길

왜 바꿨냐면 AJAX라는 문법을 jquery로 쓸건데 그거 적용하기 위해서임 

    <h1 class="ml-2 my-3">할 일 리스트</h1>
      <ul class="list-group">
        <% for (var i = 0; i < posts.length ; i++){ %>
        <li class="list-group-item">
          <h4>글 번호 : <%= posts[i]._id %></h4>
          <h4>할 일 제목 : <%= posts[i].제목 %></h4>
          <h4>할 일 마감 날짜 : <%= posts[i].날짜 %></h4>
          <button class="delete" data-id="<%= posts[i]._id %>">삭제</button>
        </li>
        <% } %>
      </ul>

우선 바디태그에서

데이터를 좀 이쁘게 꾸몄음

웹에 표시되는 데이터를 표에 집어넣어 준 것

 

거기다가 삭제 버튼도 하나 만들고

data-id라는 속성도 넣어줬다

저게 뭐냐면 posts[i]._id 값을 html요소에 집어넣을때 쓰는 속성임

 

왜 이걸 하냐면 내가 누른 삭제버튼이

몇번 id를 가진 데이터의 삭제 버튼인지 알아야하기 때문

 

삭제버튼 눌렀는데 암거나 막 삭제되면 안되잖아요

    $('.delete').click(function(e){
        // 내가 누른 요소의 data-id값을 '글번호'라는 변수에 저장
        // e.target은 지금 클릭한 것을 의미
        var 글번호 = e.target.dataset.id;
        // this는 지금 이벤트가 동작하는 곳을 의미
        var 지금누른거 = $(this);

        $.ajax({
          method : 'DELETE',
          url : '/delete',
          data : {_id : 글번호},
        }).done(function(결과){
          // 브라우저 콘솔에 뜸
          console.log('성공했음');
          // 지금 누른 버튼의 부모 태그를 찾아 줌
          // fadeOut으로 해당 태그 사라지게 함
          지금누른거.parent('li').fadeOut();
        }).fail(function(xhr, textStatus, errorThrown){
          console.log(xhr, textStatus, errorThrown);
        });
      });

다음은 script태그 부분임

저기 위에서 delete클래스를 갖고있는 버튼을 눌렀을때,

'글번호'라는 변수에 해당 버튼의 data-id에 들어있는 값을 저장해줌

e.target이 지금 클릭한 요소를 의미함

그리고 '지금누른거'라는 변수에 해당 이벤트가 동작중인 요소를 지정해줌

        $.ajax({
          method : 'DELETE',
          url : '/delete',
          data : {_id : 글번호},
        }).done(function(결과){
          // 브라우저 콘솔에 뜸
          console.log('성공했음');
          // 지금 누른 버튼의 부모 태그를 찾아 줌
          // fadeOut으로 해당 태그 사라지게 함
          지금누른거.parent('li').fadeOut();
        }).fail(function(xhr, textStatus, errorThrown){
          console.log(xhr, textStatus, errorThrown);
        });

이게 AJAX 문법인데 AJAX는 서버랑 통신할때 쓰는 자바스크립트 문법임

새로고침 없어도 서버랑 통신할 수 있는 아주 유용한 문법이라는데

암튼 AJAX문법이 편하니깐 이걸로 서버랑 통신해봅시다

 

method는 DELETE로 주세요

우린 데이터 삭제할거니깐

 

그리고 url은 /delete로 요청할겁니다

app.delete('/delete', function(req, res){
    console.log(req.body);
    req.body._id = parseInt(req.body._id);
    db.collection('post').deleteOne(req.body, function(에러, 결과){
        console.log('삭제 완료');
        // 성공 시 200번(성공) 응답 보냄
        // 실패 시 400번(실패) 응답 보냄
        // send 옵션으로 메시지도 보낼 수 있음
        res.status(200).send({message: '성공했습니다'});
        //res.status(400).send({message: '실패했습니다'});
    });
});

아까 server.js에서 /delete라는 URL을 요청받으면 DB에 있는 데이터 삭제하도록 코드 짠거 기억하시져?

 

마지막으로 data는 _id요소에 들어있는 '글번호' 변수의 값으로 전달합니다

자 이렇게 AJAX문법으로 DELETE요청을 서버에 보냈음

 

만약 요청이 성공하면?

        }).done(function(결과){
          // 브라우저 콘솔에 뜸
          console.log('성공했음');
          // 지금 누른 버튼의 부모 태그를 찾아 줌
          // fadeOut으로 해당 태그 사라지게 함
          지금누른거.parent('li').fadeOut();

done에 들어있는 이 코드를 실행해줌

'지금누른거' 변수에 들어있는 요소(지금 누른 버튼)의 부모 태그 중 li태그를 fadeOut(서서히 사라지게 하는 역할) 시켜줌

        }).fail(function(xhr, textStatus, errorThrown){
          console.log(xhr, textStatus, errorThrown);
        });

그리고 실패하면 fail에 들어있는 코드 실행시켜줌

저기 변수가 3개나 들어가는데 에러 찍어주는 변수임

머선 에러인지 알려주는 변수니까 혹시 에러나서 로그 뜨면 잘 살펴보고 해결하면 됨ㅎ

 

정리하자면,

list.ejs에서는 

(1) 내가 누른 버튼의 data-id에 저장되어있는 데이터를 '글번호'라는 변수에 저장했음

(2) ajax문법을 이용해 DELETE요청을 하는데, '글번호'변수에 들어있는 값을 /delete라는 URL로 전달함

(3) 만약에 성공했다면 '성공했음'이라고 콘솔(브라우저의)에 띄워줌

(4) '지금누른거'라는 변수에 $(this)가 저장되어 있는데 지금 누른 요소를 의미함. 그 요소의 부모태그 중 <li>태그의 내용을 fadeOut 시켜줌

 

server.js에서는

(1) /delete라는 URL로 삭제 요청이 들어오면 요청값을 req.body._id에 숫자 형태로 저장 함

(2) DB의 post라는 collection에 있는 데이터 중 req.body값을 가진 데이터 한 개를 삭제해줌

(3) 삭제 성공하면 콘솔(터미널)에 '삭제 완료'라고 띄워줌

(4) 브라우저로 status값이랑 메시지를 전달함

반응형