[에러] 한 화면 여러 폼에서, 첫 번째 폼에서만 값이 전송됨

sarifor·2022년 5월 7일
0

문제

Node.js + Express 앱(리스트의 항목별로 코멘트를 달 수 있음)에서, 첫 번째 항목의 코멘트란에 입력한 경우에는 값이 전송되고 콘솔에서 확인 가능했으나, 나머지 항목의 코멘트란에 입력한 경우에는 값 전송 및 콘솔 확인이 되지 않았다. (깃허브에서 보기)

  • 첫 번째 항목의 코멘트란에 값을 입력하고 전송한 경우

  • 두 번째 항목의 코멘트란에 값을 입력하고 전송한 경우

환경

Node.JS 14.19.1
NPM 6.14.16

원인

  • form submit 시, 함수 실행되게 하는 것 및 form 입력값의 출처가 오로지 첫 번째 form으로만 한정되어 있었음.

  • 코드(편집본)

    • home.pug

         each article in data
              form#commentForm
                  input(type="text", value="article.clickedDate)
                  button(type="submit")="Submit!"
          script(src="static/js/comment.js")                
    • comment.js

         const form = document.getElementById("commentForm")
      
          const handleSubmit = async (event) => { // async는 없어도 무방. async/await의 정확한 사용법을 몰랐을 때의 실수.
              event.preventDefault();
              const input = form.querySelector("input"); // submit event를 활용하려면 event.target.querySelector("input");이어야 함.
              const comment = input.value;
              console.log(comment);
          }
      
          if (form) {
              form.addEventListener("submit", handleSubmit); // 첫 번째 폼에만 addEventListener 붙음
          }
  • (깃허브에서 오리지널 코드 보기)

해결

  • 항목별로 submit event를 캐치할 수 있게 함.

    • 각 항목에 form(onsubmit="test(event)")루프문으로 할당.
    • submit된 값을 const input = event.target.querySelector("input");으로 인식.
  • 코드(편집본)

    • home.pug

          each article in data
              form(onsubmit="test(event)")
                  input(type="text", id=article.date, value="")
                  button(type="submit")="Submit!"
      
          script(src="static/js/comment.js")
    • comment.js

          const test = (event) => {
              event.preventDefault();
              const input = event.target.querySelector("input");
              const value = input.value;
              console.log(value);
          }
  • (깃허브에서 오리지널 코드 보기)

보충

위의 이슈 해결 과정에서 알게 된 지식을 정리하였다.
form의 값을 프론트엔드/백엔드 어디로 submit하느냐에 따른 차이점을 알아보았다.

1. form submit 시의 프론트엔드/백엔드별 이벤트 처리법 비교

  • JavaScript의 함수에 넘기기 (Front-end)

    • Form에서 서버로 값을 보내기 전에, 값을 검증하거나 추가적인 로직이 필요한 경우 Frone-end 처리를 사용한다.

    • 방법 1) onsubmit 사용

    • 방법 2) addEventListener 사용

    • onsubmit vs. addEventListener ?

      • HTML의 요소이냐, JavaScript의 요소이냐 외엔 특별히 기능상의 차이는 없는 듯하다. (확인 필요)
  • Express 함수에 넘기기 (Back-end)

    • 방법 1) req.body 사용

      • 코드 (편집본)
        • upload.pug
          form(method="POST")
              input(name="title", type="text", value="")
              input(name="desc", type="text", value="")
              input(name="tags", type="text", value="")
              input(type="submit", value="Upload")       
        • videoRouter.js
           videoRouter.route("/upload").get(getUpload).post(postUpload);
        • videoController.js
          export const postUpload = async (req, res) => {
              const { title, desc, tags } = req.body;
              (후략)
          };
      • (깃허브에서 전체 코드 보기)

요약

문제/원인/해결

  • Node.js + Express 앱의 코멘트란 여러 개 중 첫 번째에서만 값이 전송되던 원인은, form submit 시 함수 실행되게 하는 처리를 오로지 첫 번째에만 할당했기 때문이었다.
  • 코멘트란별로 form onsubmit 속성을 할당하여, 각각의 submit event를 캐치하게 함으로 해결.

보충

  • form의 값을 프론트엔드/백엔드 어디에 submit하느냐에 따라 방법이 다르다.
    프론트엔드에서 처리하는 경우엔 onsubmit이나 addEventListener를 쓰고, 백엔드에서 처리하는 경우엔 req.body에 담아 보낸다.
  • 서버로 값을 보내기 전에 값을 검증하거나 추가적인 로직이 필요한 경우에 프론트엔드 처리를 사용한다.

참고

profile
잠수 탄 블로그 같지만 살아있어요

0개의 댓글