inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

[리뉴얼] React로 NodeBird SNS 만들기

LOAD_POSTS_FAILURE 발생

269

긴장한 곰

작성한 질문수 25

0

안녕하세요! 다름이 아니라 강의를 들으며 코드를 작성하는데 게시글들을 로드하는데 있어서 계속해서 LOAD_POSTS_FAILURE가 되면서 500 상태코드의 서버에러가 발생합니다. 에러메세지를 보면 Post.findAll이 정의되지 않는다고하는데, Post가 비어있어서 finAll이 작동하지 않는 것 같습니다. 하지만 db 상으로 보면 posts 테이블이 잘 채워져있는데 왜 에러가 발생하는지 모르겠습니다ㅠㅠ 관련 코드 올려놓겠습니다.

routes/posts.js

const express = require('express');

const { PostImageUserComment } = require('../models');

const router = express.Router();


router.get('/'async (reqresnext=> {   // GET /posts
    try{
        const posts = await Post.findAll({
            limit: 10,
            order: [
                ['createdAt''DESC'],
                [Comment'createdAt''DESC']
            ],
            include: [{
                model: User,
                attributes: ['id''nickname'],
            }, {
                model: Image,
            }, {
                model: Comment,
                include: [{
                    model: User,
                    attributes: ['id''nickname'],
                }],
            }, {
                mode: User,
                as: 'Likers',
                attributes: ['id'],
            }],
        });
        console.log(posts);
        res.status(200).json(posts);
    } catch (error) {
        console.error(error);
        next(error);
    }
});

module.exports = router;

reducers/post.js

import produce from '../util/produce';

export const initialState = {
  mainPosts: [],
  imagePaths: [],
  hasMorePosts: true,
  likePostLoading: false,
  likePostDone: false,
  likePostError: null,
  unlikePostLoading: false,
  unlikePostDone: false,
  unlikePostError: null,
  loadPostsLoading: false,
  loadPostsDone: false,
  loadPostsError: null,
  addPostLoading: false,
  addPostDone: false,
  addPostError: null,
  removePostLoading: false,
  removePostDone: false,
  removePostError: null,
  addCommentLoading: false,
  addCommentDone: false,
  addCommentError: null,
};

export const LIKE_POST_REQUEST = 'LIKE_POST_REQUEST';
export const LIKE_POST_SUCCESS = 'LIKE_POST_SUCCESS';
export const LIKE_POST_FAILURE = 'LIKE_POST_FAILURE';

export const UNLIKE_POST_REQUEST = 'UNLIKE_POST_REQUEST';
export const UNLIKE_POST_SUCCESS = 'UNLIKE_POST_SUCCESS';
export const UNLIKE_POST_FAILURE = 'UNLIKE_POST_FAILURE';

export const LOAD_POSTS_REQUEST = 'LOAD_POSTS_REQUEST';
export const LOAD_POSTS_SUCCESS = 'LOAD_POSTS_SUCCESS';
export const LOAD_POSTS_FAILURE = 'LOAD_POSTS_FAILURE';

export const ADD_POST_REQUEST = 'ADD_POST_REQUEST';
export const ADD_POST_SUCCESS = 'ADD_POST_SUCCESS';
export const ADD_POST_FAILURE = 'ADD_POST_FAILURE';

export const REMOVE_POST_REQUEST = 'REMOVE_POST_REQUEST';
export const REMOVE_POST_SUCCESS = 'REMOVE_POST_SUCCESS';
export const REMOVE_POST_FAILURE = 'REMOVE_POST_FAILURE';

export const ADD_COMMENT_REQUEST = 'ADD_COMMENT_REQUEST';
export const ADD_COMMENT_SUCCESS = 'ADD_COMMENT_SUCCESS';
export const ADD_COMMENT_FAILURE = 'ADD_COMMENT_FAILURE';

export const addPost = (data=> ({
  type: ADD_POST_REQUEST,
  data,
});

export const addComment = (data=> ({
  type: ADD_COMMENT_REQUEST,
  data,
});


// 이전 상태를 액션을 통해 다음 상태로 만들어내는 함수(불변성은 지키면서)
const reducer = (state = initialStateaction=> produce(state, (draft=> {
  switch (action.type) {
    case LIKE_POST_REQUEST:
      draft.likePostLoading = true;
      draft.likePostDone = false;
      draft.likePostError = null;
      break;
    case LIKE_POST_SUCCESS: {
      const post = draft.mainPosts.find((v=> v.id === action.data.PostId);
      post.Likers.push({ id: action.data.UserId });  
      draft.likePostLoading = false;
      draft.likePostDone = true;
      break;
    }
    case LIKE_POST_FAILURE:
      draft.likePostLoading = false;
      draft.likePostError = action.error;
      break;
    case UNLIKE_POST_REQUEST:
      draft.unlikePostLoading = true;
      draft.unlikePostDone = false;
      draft.unlikePostError = null;
      break;
    case UNLIKE_POST_SUCCESS: {
      const post = draft.mainPosts.find((v=> v.id === action.data.PostId);
      post.Likers.filter((v=> v.id !== action.data.UserId);
      draft.unlikePostLoading = false;
      draft.unlikePostDone = true;
      break;
    }
    case UNLIKE_POST_FAILURE:
      draft.unlikePostLoading = false;
      draft.unlikePostError = action.error;
      break;
    case LOAD_POSTS_REQUEST:
      draft.loadPostsLoading = true;
      draft.loadPostsDone = false;
      draft.loadPostsError = null;
      break;
    case LOAD_POSTS_SUCCESS:
      draft.loadPostsLoading = false;
      draft.loadPostsDone = true;
      draft.mainPosts = draft.mainPosts.concat(action.data);
      draft.hasMorePosts = draft.mainPosts.length < 50;
      break;
    case LOAD_POSTS_FAILURE:
      draft.loadPostsLoading = false;
      draft.loadPostsError = action.error;
      break;
    case ADD_POST_REQUEST:
      draft.addPostLoading = true;
      draft.addPostDone = false;
      draft.addPostError = null;
      break;
    case ADD_POST_SUCCESS:
      draft.addPostLoading = false;
      draft.addPostDone = true;
      draft.mainPosts.unshift(action.data);
      break;
    case ADD_POST_FAILURE:
      draft.addPostLoading = false;
      draft.addPostError = action.error;
      break;
    case REMOVE_POST_REQUEST:
      draft.removePostLoading = true;
      draft.removePostDone = false;
      draft.removePostError = null;
      break;
    case REMOVE_POST_SUCCESS:
      draft.removePostLoading = false;
      draft.removePostDone = true;
      draft.mainPosts = draft.mainPosts.filter((v=> v.id !== action.data);
      break;
    case REMOVE_POST_FAILURE:
      draft.removePostLoading = false;
      draft.removePostError = action.error;
      break;
    case ADD_COMMENT_REQUEST:
      draft.addCommentLoading = true;
      draft.addCommentDone = false;
      draft.addCommentError = null;
      break;
    case ADD_COMMENT_SUCCESS: {
      const post = draft.mainPosts.find((v=> v.id === action.data.PostId);
      post.Comments.unshift(action.data);
      draft.addCommentLoading = false;
      draft.addCommentDone = true;
      break;
    }
    case ADD_COMMENT_FAILURE:
      draft.addCommentLoading = false;
      draft.addCommentError = action.error;
      break;
    default:
      break;
  }
});

export default reducer;

sagas/post.js

import axios from 'axios';
// import shortId from 'shortid';
import { alldelayforkputtakeLatestthrottlecall } from 'redux-saga/effects';

import {
  ADD_COMMENT_FAILURE,
  ADD_COMMENT_REQUEST,
  ADD_COMMENT_SUCCESS,
  ADD_POST_FAILURE,
  ADD_POST_REQUEST,
  ADD_POST_SUCCESS,
  LIKE_POST_FAILURE,
  LIKE_POST_REQUEST,
  LIKE_POST_SUCCESS,
  // generateDummyPost,
  LOAD_POSTS_FAILURE,
  LOAD_POSTS_REQUEST,
  LOAD_POSTS_SUCCESS,
  REMOVE_POST_FAILURE,
  REMOVE_POST_REQUEST,
  REMOVE_POST_SUCCESS,
  UNLIKE_POST_FAILURE,
  UNLIKE_POST_REQUEST,
  UNLIKE_POST_SUCCESS,
from '../reducers/post';
import { ADD_POST_TO_MEREMOVE_POST_OF_ME } from '../reducers/user';

function likePostAPI(data) {
  // data: post.id
  return axios.patch(`/post/${data}/like`);
}

function* likePost(action) {
  try {
    const result = yield call(likePostAPIaction.data);
    yield put({
      type: LIKE_POST_SUCCESS,
      data: result.data,
      // PostId, UserId
    });
  } catch (err) {
    console.error(err);
    yield put({
      type: LIKE_POST_FAILURE,
      data: err.response.data,
    });
  }
}

function unlikePostAPI(data) {
  return axios.delete(`/post/${data}/like`);
  // return axios.patch(`/post/${data}/unlike`); 도 가능
}

function* unlikePost(action) {
  try {
    const result = yield call(unlikePostAPIaction.data);
    yield put({
      type: UNLIKE_POST_SUCCESS,
      data: result.data,
    });
  } catch (err) {
    console.error(err);
    yield put({
      type: UNLIKE_POST_FAILURE,
      data: err.response.data,
    });
  }
}

function loadPostsAPI(data) {
  return axios.get('/posts'data);
}

function* loadPosts(action) {
  try {
    const result = yield call(loadPostsAPIaction.data);
    yield put({
      type: LOAD_POSTS_SUCCESS,
      // data: generateDummyPost(10),
      data: result.data,
    });
  } catch (err) {
    console.error(err);
    yield put({
      type: LOAD_POSTS_FAILURE,
      data: err.response.data,
    });
  }
}

function addPostAPI(data) {
  return axios.post('/post', { content: data });
}

function* addPost(action) {
  try {
    const result = yield call(addPostAPIaction.data);
    yield put({
      type: ADD_POST_SUCCESS,
      data: result.data,
    });
    yield put({
      type: ADD_POST_TO_ME,
      data: result.data.id,
    });
  } catch (err) {
    console.error(err);
    yield put({
      type: ADD_POST_FAILURE,
      data: err.response.data,
    });
  }
}

function removePostAPI(data) {
  return axios.delete('/api/post'data);
}

function* removePost(action) {
  try {
    // const result = yield call(removePostAPI, action.data);
    yield delay(1000);
    yield put({
      type: REMOVE_POST_SUCCESS,
      data: action.data,
    });
    yield put({
      type: REMOVE_POST_OF_ME,
      data: action.data,
    });
  } catch (err) {
    console.error(err);
    yield put({
      type: REMOVE_POST_FAILURE,
      data: err.response.data,
    });
  }
}

function addCommentAPI(data) {
  return axios.post(`/post/${data.postId}/comment`data);
}

function* addComment(action) {
  try {
    const result = yield call(addCommentAPIaction.data);
    yield put({
      type: ADD_COMMENT_SUCCESS,
      data: result.data,
    });
  } catch (err) {
    yield put({
      type: ADD_COMMENT_FAILURE,
      data: err.response.data,
    });
  }
}

function* watchLikePost() {
  yield takeLatest(LIKE_POST_REQUESTlikePost);
}

function* watchUnlikePost() {
  yield takeLatest(UNLIKE_POST_REQUESTunlikePost);
}

function* watchLoadPosts() {
  yield throttle(5000LOAD_POSTS_REQUESTloadPosts);
}

function* watchAddPost() {
  yield takeLatest(ADD_POST_REQUESTaddPost);
}

function* watchRemovePost() {
  yield takeLatest(REMOVE_POST_REQUESTremovePost);
}

function* watchAddComment() {
  yield takeLatest(ADD_COMMENT_REQUESTaddComment);
}

export default function* postSaga() {
  yield all([
    fork(watchLikePost),
    fork(watchUnlikePost),
    fork(watchAddPost),
    fork(watchLoadPosts),
    fork(watchRemovePost),
    fork(watchAddComment),
  ]);
}

react nodejs express redux Next.js

답변 1

0

제로초(조현영)

모델로부터 불러온 Post 객체가 undefined인 겁니다. export에서 문제가 있었겠죠.

0

긴장한 곰

해결했습니다! :) 주석 달면서 Post 모델에 문제가 생겼던 것 같습니다

넥스트 버젼 질문

0

90

2

로그인시 401 Unauthorized 오류가 뜹니다

0

104

1

무한 스크롤 중 스크롤 튐 현상

0

192

1

특정 페이지 접근을 막고 싶을 때

0

116

2

createGlobalStyle의 위치와 영향범위

0

102

2

인라인 스타일 리렌더링 관련

0

98

2

vsc 에서 npm init 설치시 오류

0

157

2

nextjs 15버전 사용 가능할까요?

0

166

1

화면 새로고침 문의

0

129

1

RTK에서 draft, state 차이가 있나요?

0

160

2

Next 14 사용해도 될까요?

0

455

1

next, node 버전 / 폴더 구조 질문 드립니다.

0

359

1

url 오류 질문있습니다

0

214

1

ssh xxxxx로 우분투에 들어가려니까 port 22: Connection timed out

0

391

1

sudo certbot --nginx 에러

0

1293

2

Minified React error 콘솔에러 (hydrate)

0

477

1

카카오 공유했을 때 이전에 작성했던 글이 나오는 버그

0

255

1

프론트서버 배포 후 EADDRINUSE에러 발생

0

337

1

npm run build 에러

0

525

1

front 서버 npm run build 중에 발생한 에러들

0

399

1

서버 실행하고 브라우저로 들어갔을때 404에러

0

350

2

css 서버사이드 랜더링이 적용되지 않아서 문의 드립니다.

0

290

1

팔로워 3명씩 불러오고 데이터 합쳐주는걸로 바꾸고 서버요청을 무한으로하고있습니다.

0

249

2

해시태그 검색에서 throttle에 관해 질문있습니다.

0

206

1