게시판 만들기 #8 / Update

jh_leitmotif·2021년 7월 24일
0
post-thumbnail

🧐 개요

Node.js CRUD 게시판 생성을 정리합니다.

Update입니다.

📋 postDetail.html

<!DOCTYPE html>
<html>
  <head>
    <title>글 수정하기</title>
    <link rel='stylesheet' href='../../../css/style.css' />
  </head>
  <body>
    <div class="ContentField">
      <form action="/board/update" method="post">
        <table frame=void>
          <input type="hidden" name="idx" value="<%=rows[0].idx%>"/>
          <tr>
             <td colspan="2">
               <input type="text" name="title" value="<%=rows[0].title%>" > 
            </td>
          </tr>
          <tr>
            <td colspan="2">
               <textarea style="border:none; width:100%; height:100%; padding-top:20px; font-size:1.3em" name="content"  required ><%=rows[0].content%></textarea>
            </td>
          </tr>
          <tr>
            <td colspan="2" style="text-align:right;">
                <button type="submit">글 수정</button>
                <button type="button" onclick="location.href='../list/post/'+<%=rows[0].idx%>">뒤로 가기</button>
            </td>
        </tr>
        </table>
        </form>
    </div>
  </body>
</html>

글 수정 페이지는 글 작성자가 수정 버튼을 클릭해야 접근할 수 있습니다.

역시 마찬가지로, 파일 업로드와 관련된 부분은 모두 제외했습니다.

딱히 특이사항은 없으며, 글 제목과 내용이 서버로 전달됩니다.


📋 글 수정 접근 라우터

router.get('/board/update/:idx',(req,res)=>{
  const idx = req.params.idx;
  req.session.updateIdx = idx;
  conn.getConnection((err,connection)=>{
    if (err) throw err;
    const query = connection.query('SELECT idx, title, name, content FROM board WHERE idx='+idx, function(err,rows){
      if (err) throw err;
      if (rows[0].name==req.session.displayName){
        res.render('boardHTML/postDetail.html',{rows:rows});
      }else{
        res.send("<script>alert('작성자가 아닙니다.'); document.location.href='/board/list'</script>")
      }
      connection.release();
    })
  })
})

글 수정 버튼을 누르면 포스트의 ID가 파라미터로 서버에 넘겨집니다.

이 파라미터를 통해 렌더링되는 html에 기존의 제목과 내용을 넘깁니다.

특이사항이라면, 혹시나 글 작성자가 아닌 사용자가 URL로 직접 접근한 경우
작성자가 아니라는 alert를 발생시키고, 게시판 페이지로 보냅니다.


📋 post 라우터 - DB에 값 갱신하기

실제로 값을 업데이트하는 post 라우터는 두 개의 Promise로 나뉩니다.

let selQuery = function(){
      return new Promise(function(resolve,reject){
        const sql = 'SELECT uploadfilepath FROM board WHERE idx=?';
        connection.query(sql,[idx],(err,rows)=>{
          if (err) reject(err);
          if (rows.length==0 || (rows[0].uploadfilepath==null || rows[0].uploadfilepath=='')){
            reject('There is no path in DB');
          }else{
            fileList = rows[0].uploadfilepath;
            resolve('Detect path from DB');
          }
        })
      })

첫 번째 Promise는 해당 포스트에 첨부된 파일이 있는지 여부를 검사합니다.

첨부된 파일이 있다면 fileList 변수에 DB에 저장된 경로값을 가져옵니다.
만약 없다면 fileList = '' 입니다.
연결해서, 컬럼에 값이 있다면 fulfill을, 없다면 reject를 반환합니다.


let updateQuery = function(){
      return new Promise(function(resolve,reject){
        const sql = 'UPDATE board SET title=?, content=?, uploadfilepath=?, modidate=NOW() WHERE idx=?'
        connection.query(sql,[title,content,filepath,idx],function(err,rows){
          if (err) reject(err);
          res.send("<script>alert('작성되었습니다.'); document.location.href='/board/list'</script>")
          connection.release();
          resolve('Update path in DB');
        })
      })
    }

두 번째 Promise는 단순한 Update 쿼리입니다.

전달받은 제목, 내용을 DB에 업데이트합니다.

파일 경로는 선행된 첫 번째 Promise의 결과에 따라서

  1. 기존 경로값 유지
  2. 새로운 경로값 생성
  3. 경로가 없음

셋 중 하나로 결정됩니다.

첫 번째 Promise가 fulfill 상태였다면 1, 또는 2로 파일 경로가 정해져 후행됩니다.

첫 번째 Promise가 reject 상태였다면 3으로 파일 경로가 정해지고 후행됩니다.


let worker = async function(){
      try{
          console.log(await selQuery());
          if (filepath!=null){
            filepath = fileList+'+'+filepath;
          }else{
            filepath=fileList;
          }
          console.log(await updateQuery());
      }catch{
          console.log(await updateQuery());
      }
    }
    worker();

Promise 실행부입니다.

첫 번째 Promise는 파일 경로가 있으면 fulfill, 없으면 reject상태를 반환합니다.

따라서 try, catch 문법을 통해 수행을 분기합니다.

만약 파일 경로가 존재하는 경우 업데이트할 파일 경로를 정하고
두 번째 Promise를 수행합니다.

존재하지 않는다면 파일 경로를 정하는 부분을 제외하고, 두 번째 Promise를 곧바로 수행합니다.


🎯 구조도


🙄 후기

파일 다운로드 구현에서 Async, await를 만난 이후

처음으로 콜백 방식으로 되어있던 것을 수정했던 Update 부분입니다.

다행(?)스럽게도 현재 구현된 기능들 중
작성된 글을 보는 것과 글을 작성하는 post 라우터 정도를 제외하면
콜백 방식에서 변경할 필요성은 보이지 않는 것 같습니다.

Async/await 방식을 사용해보며 계속 체감하고있는 것은

Node.js의 비동기적처리를 보기 쉽게 순차적으로 정리하면서 코드가 깔끔해지고

주석달기, 실행 순서를 제어하는 부분에 대해 편리함을 느끼고 있습니다.

profile
Define the undefined.

0개의 댓글