1. 발생 계기
듣고있는 강의의 예제 웹 사이트에서 실험적으로 로그인 이후 게시글을 작성할 때, 오류가 발생. 오류 자체는 간단한 undefined 문제였지만, 이러한 undefined 가 나오게 된 과정을 찾는게 문제였다.
2. 탐구해본 원인
우선 나타난 오류를 살펴보게 되면, post.User 부분이 undefined 가 나오기 때문에 오류가 발생하였다. 위 컴포넌트 PostCard 의 경우 어떠한 데이터를 가져오는지 확인했었는데, post 부분이 실제 유저가 작성한 게시글을 가져온 것이고, 이 post 에 User 가 담겨있지 않다고 해석하였다. 다만 아직 왜 담겨있지 않은지 파악하지 못하였다.
3. 해결 과정
일단 post 에 User 가 담기지 않았다는 것을 주목하였다. 여기서 User 는 실제 mysql 상 model 부분의 user 데이터베이스를 뜻한다.
{post.User.id === id } 라는 의미는 현재 사용자의 id 가 데이터베이스 상 User 의 id 와 같냐고 물어보는 것이고, 이는 결국 현재 로그인되어있는 사용자의 id 가 현 게시글의 작성자 id 와 같냐고 물어보는 것이다. 게시글을 수정하려면 그 게시글을 작성한 유저입장에서 가능한 것이니깐
이렇게 따져보니 User 를 가져오지 못했다는 의미이고, post 를 가져오는 과정에서 문제가 있겠다 판단하였다. 그럼 post 는 어디서 오는 것일까
기본적으로 프론트에 전달되는 것은 saga 와 reducer 를 통해서 이지만, 일단 게시글을 작성하여 전송을 누르면 API 를 통해 백엔드 서버에 전송한다.
아래 코드에서 req.body.content 부분이 유저가 작성한 게시글 내용이다. 여기에 userId 를 첨부해서 데이터베이스 Post 에 넣어주고 있다. 그 다음 이 넣어진 데이터를 다시 프론트엔드 서버로 가져와서 렌더링을 해야한다. 이때 프론트에 전달하는 것이 post 이다.
따라서 이 post 안에 게시글 외의 데이터, 즉 Image 나 User 데이터베이스에서 이 게시글과 연관된 데이터를 같이 넘겨주면 될 것이라 판단하였다.
- routers/post.js
router.post("/", isLoggedIn, async (req, res, next) => {
try {
console.log("req.user.id", req.user.id);
const post = await Post.create({
content: req.body.content,
userId: req.user.id,
});
res.status(201).json(post);
} catch (err) {
console.error(err);
next(err);
}
});
위 코드를 이렇게 바꿔주자
router.post("/", isLoggedIn, async (req, res, next) => {
try {
console.log("req.user.id", req.user.id);
const post = await Post.create({
content: req.body.content,
userId: req.user.id,
});
const fullPost = await Post.findOne({
where: { id: post.id },
include: [
{
model: Image,
},
{
model: Comment,
},
{
model: User,
},
],
});
res.status(201).json(fullPost);
} catch (err) {
console.error(err);
next(err);
}
});
이렇게 변경해주고 다시 웹사이트를 실행하여 게시글을 작성해보았다..
근데 같은 에러가 또 뜬다. 해결이 되지 않았다... 어째서 일까. 일단 redux store 를 확인해보고자 하였다.
분명 Image 와 Comment 는 데이터베이스에서 잘 가지고 왔다. 허나 User 부분에서 문제가 보였다. 왜그런것일까.
파악하기 힘들어 일단 MySql 데이터베이스를 참조해봤다.
여기서 이상한 점을 발견했는데, 모든 게시글 데이터는 잘 데이터베이스에 저장이 되고 있었다. 그렇다는 말은 실제 프론트서버와 벡엔드 서버는 연동이 잘 되고 있음을 확인할 수 있었다.
허나 주목할 점이 UserId 가 null 값으로 들어오지 못하고 있었다. 왜 이런 일이 발생한 것일까... 일단 이 UserId 를 어디서 전달하는지부터 파악할 필요가 있었다. 내 기억속에서는 userId 의 경우 post router 에서 담당하는것으로 알고 있었다. 그래서 코드를 다시 확인해보니,
router.post("/", isLoggedIn, async (req, res, next) => {
try {
console.log("req.user.id", req.user.id);
const post = await Post.create({
content: req.body.content,
UserId: req.user.id, // userId -> UserId
});
const fullPost = await Post.findOne({
where: { id: post.id },
include: [
{
model: Image,
},
{
model: Comment,
},
{
model: User,
},
],
});
res.status(201).json(fullPost);
} catch (err) {
console.error(err);
next(err);
}
});
req.user 에는 분명 현 로그인 한 사용자의 id 가 담겨있다. desequelizeUser 부분에서 유저 정보를 복구하였기 때문이다. 여긴 문제가 없다면, 결국 데이터에 넣어줄 때 문제가 있는 것이고, 잘 살펴보니 userId 가 아니라 UserId 로 했어야 했음을 깨달았다!!...

또한 실수한 부분이 또 있었는데, 데이터베이스의 이름을 설정해주는 부분에서, 역시나 실수가 있었다. 아까 위에서 store 부분에서 User 가 null 이 나오는 것을 확인할 수 있었는데, 이는 아예 접근을 못했다고 해석이 들었고, 어디에 문제가 있나 살펴보던 중
module.exports = class User extends Model {
static init(sequelize) {
return super.init(
{
email: {
// 생략
},
{
// 유저 모델에 대한 셋팅
modelName: "User", // "user" -> "User"
tableName: "users",
charset: "utf8",
collate: "utf8_general_ci",
sequelize,
}
);
}
modelName 부분을 "user" 로 해놓았다... 다시 User 로 변경한 다음, 다시 게시글을 작성해보니
데이터베이스에도 잘 들어가고, 화면 역시 오류가 사라지고 잘 렌더링 됨을 확인하였다!
잘못된 지식때문에 이걸 해결하는데 꽤나 시간이 걸렸다. 너무나 당연하게 작성한 코드때문에... 그래도 항상 오류의 해결과정은 흐름을 파악하고, 어떤것이 원인일까 생각하면서, 파악이 잘 끝났다면 구글의 도움을 통해..!
'Programing > Error' 카테고리의 다른 글
[ERROR] The user specified as a definer ('mysql.infoschema'@'localhost') does not exist (0) | 2023.01.05 |
---|---|
[ERROR]MySql root 비밀번호 설정 시 에러 (0) | 2023.01.05 |
Error : Access denied for user '유저아이디'@'localhost' (using password: YES) 해결 및 mysql 비밀번호 초기화 (0) | 2022.11.16 |
Error : because it would overwrite input file (0) | 2022.11.12 |
Error: Invalid Hook Call Warning (1) | 2022.10.29 |