Mern,删除评论问题

Posted

技术标签:

【中文标题】Mern,删除评论问题【英文标题】:Mern, Deleting comments issue 【发布时间】:2020-05-07 21:47:05 【问题描述】:

我无法删除单个帖子中的 cmets。我不知道是什么原因造成的,但显然我收到了 404 错误,老实说,我不知道为什么找不到该帖子。我很想获得帮助,看看是什么原因造成的,为什么我会收到这个错误,以及为什么我无法从帖子中删除评论。下面我将发布我的一些后端以及我的前端代码,但我也会确保链接到我的 Github 下面。我已经为此苦苦挣扎了将近 3 天,我没有看到究竟是什么导致了错误,我希望得到一些帮助。 另一件要提的是,我对 MERN 还很陌生,所以也请看看我的 Github 代码,并提出更改或我可以做得更好的建议,老实说,这对我来说意义重大。 下面是这个特定项目的一些代码和我的 Github 存储库的链接

https://github.com/tigerabrodi/ELance

从帖子中删除评论的路径


// @route    DELETE api/posts/comment/:commentId 
// @desc     Delete comment
// @access   Private
router.delete("/comment/:commentId", auth, async (req, res) => 
  try 
    const comment = await Comment.findById(req.params.commentId);

    if (!comment) 
      return res.status(404).json( msg: "Comment do not exist" );
    

    if (comment.user.toString() !== req.user.id) 
      return res.status(401).json( msg: "User not authorized" );
    

    await comment.remove();

    res.json(msg: "Comment Removed")
   catch (err) 
    console.error(err.message);
    res.status(500).send("Server Error");
  
);

module.exports = router;

Post.js

import React,  Fragment, useEffect  from 'react';
import  Link  from 'react-router-dom';
import  connect  from 'react-redux';
import Spinner from '../layout/Spinner';
import PostItem from '../posts/PostItem';
import CommentForm from '../post/CommentForm';
import CommentItem from '../post/CommentItem';
import  getPost  from '../../redux/post/post.actions';
import getSinglePostComments from "../../redux/comment/comment.actions"

const Post = ( getPost, getSinglePostComments, post:  post, loading , comment, match ) => 
  useEffect(() => 
    getPost(match.params.id);
    getSinglePostComments(match.params.id)
  , [comment.comments]);

  return loading || comment.loading || post === null ? (
    <Spinner />
  ) : (
    <Fragment>
      <Link to='/posts' className='btn btn-info m-3'>
        Back To Posts
      </Link>
      <PostItem post=post showActions=false />
      <CommentForm postId=post._id />
      <div className='comments'>
        comment.comments.map(comment => (
          <CommentItem key=comment._id comment=comment />
        ))
      </div>
    </Fragment>
  );
;

const mapStateToProps = state => (
  post: state.post,
  comment: state.comment
);

export default connect(
  mapStateToProps,
   getPost, getSinglePostComments 
)(Post);

CommentItem.js

import React from 'react';
import  Link  from 'react-router-dom';
import  connect  from 'react-redux';
import Moment from 'react-moment';
import deleteComment from '../../redux/comment/comment.actions';
import defaultUserImage from "../../assets/default-user-icon.jpg"

const CommentItem = (
  comment:  _id, text, user, date ,
  auth,
  deleteComment
) => (

    <div class="card m-5 bg-warning">
  <div class="row no-gutters align-items-center">
    <div class="col-md-2">
    <Link to=`/profile/$user._id`>
            <img className='card-img rounded-circle pl-2' src=user.avatar ? user.avatar : defaultUserImage alt='' />
            </Link>
    </div>
    <div class="col-md-10">
      <div class="card-body">
        <h5 class="card-title text-center">user.name</h5>
        <p class="card-text">text</p>
        <p class="card-text"><small class="text-muted">Posted on <Moment format='YYYY/MM/DD'>date</Moment>
</small></p>
      !auth.loading && user._id === auth.user._id && (
        <button
          onClick=() => deleteComment(_id)
          type='button'
          className='btn btn-danger float-right mb-4'
        >
          <i className='fas fa-times' />
        </button>
      )
      </div>
    </div>
  </div>
</div>
);

const mapStateToProps = state => (
  auth: state.auth
);

export default connect(
  mapStateToProps,
   deleteComment 
)(CommentItem);

CommentForm.js

import React,  useState  from 'react';
import  connect  from 'react-redux';
import  addComment  from '../../redux/comment/comment.actions';

const CommentForm = ( postId, addComment ) => 
  const [text, setText] = useState('');

  return (
    <div className='container'>
        <div className="row">
        <div className="col text-center">
         <div>
        <h4>Leave a Comment</h4>
      </div>
      <form
        className='form my-1 d-flex flex-row align-items-center justify-content-center'
        onSubmit=e => 
          e.preventDefault();
          addComment(postId,  text );
          setText('');
        
      >
        <textarea
          name='text'
          className="form-control bg-info text-light"
          placeholder='Comment the post'
          value=text
          onChange=e => setText(e.target.value)
          required
        />
        <input type='submit' className='btn btn-outline-info ml-3' value='Submit' />
      </form>
    </div>
        </div>
        </div>

  );
;

export default connect(
  null,
   addComment 
)(CommentForm);

comment.actions.js

import axios from "axios";
import setAlert from "../alert/alert.actions"
import CommentActionTypes from "./comment.types"


// Get Comments For a Single Post
export const getSinglePostComments = id => async dispatch => 
  try 
    const res = await axios.get(`/api/posts/comments/$id`);

    dispatch(
      type: CommentActionTypes.GET_SINGLE_POST_COMMENTS,
      payload: res.data
    );
   catch (err) 
    dispatch(
      type: CommentActionTypes.COMMENT_ERROR,
      payload:  msg: err.response.statusText, status: err.response.status 
    );
  
;



  // Add Comment
  export const addComment = (postId, formData) => async dispatch => 
    const config = 
      headers: 
        'Content-Type': 'application/json'
      
    ;

    try 
        const res = await axios.post(`/api/posts/comment/$postId`, formData, config);

        dispatch(
          type: CommentActionTypes.ADD_COMMENT,
          payload: res.data
        );
       catch (err) 
        dispatch(
          type: CommentActionTypes.COMMENT_ERROR,
          payload:  msg: err.response.statusText, status: err.response.status 
        );
      
  

 // Delete comment
export const deleteComment = (commentId) => async dispatch => 
  try 
    await axios.delete(`api/posts/comment/$commentId`);

    dispatch(
      type: CommentActionTypes.DELETE_COMMENT,
      payload: commentId
    );

    dispatch(setAlert('Comment Removed', 'success'));
   catch (err) 
    dispatch(
      type: CommentActionTypes.COMMENT_ERROR,
      payload:  msg: err.response.statusText, status: err.response.status 
    );
  
;  

comment.reducer.js

import CommentActionTypes from "./comment.types";



const initialState = 
    comments: [],
    loading: true,
    error: 


const commentReducer = (state = initialState, action) => 
    const payload, type = action;
    switch (type) 
            case CommentActionTypes.GET_SINGLE_POST_COMMENTS:
                return 
                    ...state,
                    comments: payload,
                    loading: false
                
            case CommentActionTypes.ADD_COMMENT:
                return 
                    ...state,
                    comments: [payload, ...state.comments],
                    loading: false
                
            case CommentActionTypes.DELETE_COMMENT:
                return 
                    ...state,
                    comments: state.comments.filter(comment => comment._id !== payload),
                    loading: false
                
            case CommentActionTypes.COMMENT_ERROR:
                return 
                    ...state,
                    error: payload,
                    loading: false
                
        default:
            return state;
    


export default commentReducer

comment.types.js

export const CommentActionTypes = 
    DELETE_COMMENT: "DELETE_COMMENT",
    ADD_COMMENT: "ADD_COMMENT",
    COMMENT_ERROR: "COMMENT_ERROR",
    GET_SINGLE_POST_COMMENTS: "GET_SINGLE_POST_COMMENTS"

【问题讨论】:

虽然我可以为您调试您的代码,但我认为您不会通过自己动手来了解调试过程。所以,相反,我会给你一些提示:在你的后端安装 morgan(它是一个日志框架,将你的 API 请求记录到控制台),然后分解每个步骤: 1.) 是否调用了 redux 操作和右边的id? 2.) API 调用是否到达后端(这就是摩根派上用场的地方)。 3.) 请求是否到达正确的控制器? 4.) 控制器是否收到id 并且它是否匹配已经存在的comment 记录? 某处,在这些步骤之一,将是你的问题。请记住,您可以 console.log 每个步骤以确保它们正常执行和/或查看它们是否抛出错误。为了让事情变得更简单,您可以使用 postman (getpostman.com) 将请求直接发送到 API,您可以使用 MongoDB Compass 查看当前的 Mongo 数据库和文档:mongodb.com/products/compass。如果您仍然卡住,请告诉我,我会提供帮助。但是,我鼓励您先尝试上述方法。 顺便说一句,我确实尝试过调试,第二件事,它适用于邮递员,您可以删除评论,我昨天试过了。第三件事,我相信这是一个前端问题,因为我得到一个 404 说“未找到”,虽然我确实设置了一个 404 错误,如果不存在 cmets 说:评论不存在。出于这个原因,老实说,我不知道还能做什么,前端似乎很好,后端也...... 如果你能调试它,我仍然会很高兴,我已经为此苦苦挣扎了将近 2-3 天,至少今天能完成它会很棒,因为我没有任何学校。我什至求你调试它。 我不会继续调试,我确实设置了 morgan 并再次检查了后端,后端工作正常,我现在将通过进入应用程序检查前端部分是否工作. 【参考方案1】:

在comment.actions.js的deleteComment方法中,需要在delete url的开头添加一个斜杠:

    await axios.delete(`/api/posts/comment/$commentId`);

【讨论】:

天哪,你救了我的命,我不认识你,但有一件事是肯定的,愿上帝保佑你,伙计。这是一个小错字,哈哈哈谢谢大佬! 我还有 10 小时的时间来编写新功能,而不是哭闹和调试

以上是关于Mern,删除评论问题的主要内容,如果未能解决你的问题,请参考以下文章

MERN - TypeError:无法读取未定义的属性“id”

MERN 应用程序中的重复选项卡问题

Reactstrap Form 重置输入值 MERN 堆栈

如何在堆栈 MERN 中建立这种关系?

mern 堆栈中的路由是如何处理的?

为啥我在将 MERN 部署到 Heroku 期间错误地收到文件丢失错误?