[ Node ] DB 데이터 삽입 시 동적으로 생성되는 id값을프론트단에서 바로 사용하기.

방충림·2023년 3월 23일
3

Catch the error

목록 보기
2/7
post-thumbnail

코드 설명

다음은 스케줄러 프로젝트의 일부분이다.
스캐줄러는 일정을 입력하면, DB에 정보를 저장함과 동시에 UI상에 새로운 일정을 띄워주는 것이 핵심 동작이다.

아래와 같은 코드가 있다. 프론트단에서 axios로 서버와 통신을 하는 코드이고. rest API로 insert문을 실행시킨다. (사실 URI에 저렇게 동사를 쓰는 것은 권고되진 않는다.참고.)

프론트 앤드 단 코드

function handleModalSubmit() {
    setOpen(false);
    const { title, start, end, color, locale } = newEvent;
    // Send POST request to server to add new event
    axios
      .post("http://localhost:5000/scheduler/insert", {
        title,
        start,
        end,
        color,
        locale,
        allDay: false,
      })
      .then((response) => {
        console.log("잠시 검문있겠슙니다", response.data);
        alert("등록성공!");
        // Add newly created event to calendar
        setCurrentEvents((currentEvents) => [
          ...currentEvents,
          {
            id: response.data.id,
            title: response.data.title,
            start: response.data.start,
            end: response.data.end,
            color: response.data.color,
            locale: response.data.locale,
            allDay: false,
          },
        ]);
      })
      .catch(() => {
        alert("등록실패");
      })
      .finally(() => {
        setNewEvent({
          title: "",
          start: "",
          end: "",
          color: "",
          locale: "",
        });
      });
  }

백엔드 단 코드

router.post("/insert", (req, res) => {
  const title = req.body.title;
  const start = req.body.start;
  const end = req.body.end;
  const color = req.body.color;
  const locale = req.body.locale;
  const sqlQuery =
    "INSERT INTO event_list(title,start,end,color,locale) VALUES(?,?,?,?,?);";
  db.query(sqlQuery, [title, start, end, color, locale], (err, result) => {
    if (err) {
      console.log(err);
    } else {
      res.send(res.body);
      console.log("result", result);
      console.log("res.body", res.body);
    }
  });
});

문제 원인

다만 이 코드는 문제가 있다.

나는 insert한 직후 즉시 id값을 사용해야만하는데. 페이지를 새로고침을 하여 데이터를 DB에서 새로 받아오지 않는이상 id는 빈 상태로 프로트단에 남아있기 때문이다.

그로인한 사로한 버그들이 생긴다.
예를 들어 id를 참조해야하는 동작인 UPDATE와 DELETE의 경우에는, 이벤트를 생성하자마자 새로고침 없이 수정 삭제를 진행했을 때, UI상으로는 반영된 듯 보였으나 이후 새로고침을 하면 다시 원래 상태로 돌아옴을 알 수 있었다.
이것은 id를 참조하지 못한채로 동작이 이루어졌고 떄문에 db에 동작이 전달되지 못해서 이다.

이를 해결하려면? 그렇다 아이디를 받아와야한다.

해결 방안

그런데 그냥 위와같이 일반적으로 res.body를 통해서 받아오려고 하면 당연히 id를 찾을 수 없다. 다른 방법을 이용해야한다. 그것은 바로 result.insertId 를 이용하는 것이다.

수정한 코드

이것을 사용하여 작성한 코드는 아래와 같다.

router.post("/insert", (req, res) => {
  const title = req.body.title;
  const start = req.body.start;
  const end = req.body.end;
  const color = req.body.color;
  const locale = req.body.locale;
  const sqlQuery =
    "INSERT INTO event_list(title,start,end,color,locale) VALUES(?,?,?,?,?);";
  db.query(sqlQuery, [title, start, end, color, locale], (err, result) => {
    if (err) {
      console.log(err);
    } else {
      const newEvent = {
        id: result.insertId, // Get the newly inserted id
        title,
        start,
        end,
        color,
        locale,
        allDay: false,
      };
      res.send(newEvent);
      console.log("과연 아이디를 받아올 수 있을 것인가", result.insertId);
    }
  });
});

이렇게 할시에 id가 즉시 받아와지고 프로트단에서도 바로 사용할 수 있게 된다.

profile
최선이 반복되면 최고가 된다.

0개의 댓글