내가 기억하려 쓰는 MVC-MySql 연동 회원가입/로그인/회원정보 수정/회원탈퇴 에러,,,,,,
부끄러운 말이지만 나에겐 참 어렵고 에러 원인을 모르겠어서 10시간 넘게 에러와 씨름했다........ 하면서 이제와서 코딩이 적성에 안 맞는 것일까 자괴감도 참 들었다....
흑흑..... 그래서 자극받아서 책도 시켰다 ㅎㅎ..
아무튼 가장 대표적이었던 에러를 써보겠습니다.
죽어도 input에 값이 채워지지 않았다.
console.log를 거의 model, controller, front js 구문 한 줄마다 작성한 것 같다.
function login() {
const form_login = document.forms["form_login"];
const info = {
id: form_login.userid.value,
pw: form_login.pw.value,
};
try {
axios({
method: "post",
url: "/user/signin",
data: info,
}).then((response) => {
const { state } = response.data;
console.log("state", state);
console.log("data | login |signin.ejs", response.data);
if (state === "Success") {
let form_info = document.forms["form_info"];
console.log("1", form_login.userid.value);
form_info.userid.value = form_login.userid.value;
console.log("2", form_info.userid.value);
alert("로그인 성공!");
form_info.submit(); //action="/user/profile" 으로 post
document.location.href = "/user/profile";
//페이지 이동되며 새로고침 되는 메소드이므로 중복해 쓰이고 있었음
}
}
나는 코드와 같이 폼의 이름과 값을 변수에 저장한 후, axios를 통해 post 하고 +
document.location.href = "/user/profile"
를 통해 페이지를 이동했다.
라우터에서는 post 코드와 더불어 페이지 이동을 위해 get도 하고 있었다.
router.get("/user/profile", controller.viewPro);
// 프로필 페이지로 이동 - 회원정보 보내기
router.post("/user/profile", controller.viewPro);
그러니까, 총 profile 페이지로의 이동을 3번이나!! 한 셈이다.
처음으로는 router의 코드를 주석처리했다.
그 후, 처음 안 사실인데
document.location.href
는 페이지를 이동하며 새로고침 역시 같이 해 값이 받아와지지 않는 것이었다.
따라서 이 역시 주석 처리했다.
값이 전달되긴 했으나, userid만 전달되어 나머지 pw, name은 보여지지 않았다.
에러 부분 주요 코드는 다음과 같다,
exports.viewPro = (req, res) => {
console.log("req.body | viewPro | Cuser.js", req.body); //{ userid: 'd' }
User.viewPro(req.body, (result) => {
console.log("result | viewPro | Cuser.js", result);
res.render("profile", { data: result });
});
};
exports.viewPro = (userid, cb) => {
const sql = `SELECT * FROM user WHERE userid="${userid}" LIMIT 1`;
console.log(userid); // {userid : 'd'}
conn.query(sql, (err, rows) => {
if (err) {
throw err;
}
// console.log("rows", rows); // []
cb(rows);
});
};
<form name="form_profile">
<label for="userid">ID</label>
<input type="hidden" id="id" value="<%=data.id%>" />
<!-- readonly: userid는 수정 불가능 (조건임) -->
<input
id="userid"
type="text"
name="userid"
value="<%=data.userid%>"
readonly
/><br />
<h1><%=data.id%></h1>
<label for="password">Password</label>
<input
id="password"
type="password"
name="pw"
value="<%=data.pw%>"
required
/><br />
<label for="name">Name</label>
<input
id="name"
type="text"
name="name"
value="<%=data.name%>"
required
/>
그러나 User.js에서 sql문도 올바르고, userid도 잘 받아왔는데, controller에 전달되는 rows로는 빈 값이 전달되는 것이었다. 그러니 당연히 프론트에서도 값이 보여지지 않았다.
sql문의 결과가 빈 값이라고 결론을 내리고, 하나씩 추적해갔다.
sql문의 결과가 빈 값이라면, 조건인 WHERE문에 전달되는 userid가 이상할 것이 분명했다.
exports.viewPro = (req, res) => {
console.log("회원정보 보기");
console.log("req.body | viewPro | Cuser.js", req.body); //{ userid: 'd' }
User.viewPro(req.body, (result) => {
console.log("result | viewPro | Cuser.js", result); //[ RowDataPacket { id: 5, userid: 'd', name: 'd', pw: 'd' } ]
res.render("profile", { data: req.body });
});
};
나는 값이 찍힌다는 것에 현혹되어서 콜백함수의 result가 아닌 req.body를 보내고 있었다.
그래서 result를 보냈다.
그러니까 이번엔 아무것도 안 찍혔다!!!!!!
result를 console.log로 찍어보아도
[ RowDataPacket { id: 5, userid: 'd', name: 'd', pw: 'd' } ]
값이 잘 들어있었다 엥....
그렇게 화면을 노려보던 중, result는 배열임을 발견했고
res.render("profile", { data: result[0] }); //인덱싱 중요!!!!
result[0]을 보내니, 드디어....
아이고 흑흑......
이제 성공적으로 값을 불러왔으니 수정과 회원탈퇴 기능을 손보러 가봐야겠다..
배운 게 아주 많고 앞으로도 많을 과제였다..
데이터베이스.. 몇개까지 추가될까.?
아무튼 MVC의 데이터의 순환이 참 헷갈렸는데 이제는 어렴풋이 알 것 같다ㅎㅎ
아주 감사했던 리더님의 답변 🫰🏻🫰🏻