无法在 Mern 堆栈应用程序中使用 axios.put 更新 mongodb 对象
Cannot update mogodb object with axios.put in Mern stack app
我需要从我的 mongodb 数据库“评论”集合中更新我的“评论”对象。更具体地说,当我按下“喜欢”按钮时,我想发送一个带有 axios 的放置请求,我可以在其中将 + 1 添加到“评论”对象的“喜欢”。
所有其他操作都正常(获取评论、添加评论等),我唯一遇到困难的是更新评论赞。
如果有人能提供帮助,我将不胜感激。提前致谢!
我在下面添加了我的代码:
//--------CommentComponent.js
import React, { useState, useEffect } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { getComments, updateComment } from '../actions/commentActions'
const PostPage = ({ match }) => {
const commentz = useSelector(store => store.comment.comments)
const dispatch = useDispatch()
useEffect(() => {
dispatch(getComments())
}, [dispatch])
const handleLike = e => {
dispatch(updateComment(e.target.id))
}
return (
{commentz ? commentz.map(comm =>
comm.forWich === match.params.id ?
<div key={comm._id} className={styles.comment}>
<div>
<h2>{comm.name}</h2>
</div>
<div>
<p>{comm.comment}</p>
</div>
{comm.likes} <button id={comm} onClick={handleLike}>Like</button>
<div>
</div>
: null
) : null}
)
}
export default PostPage
//--------Comment.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// Create Schema
const CommentSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
comment: {
type: String,
required: true
},
forWich: {
type: String,
required: true
},
likes: {
type: Number,
default: 0
},
date: {
type: Date,
default: Date.now
}
});
module.exports = Comment = mongoose.model('comment', CommentSchema);
//--------comments.js
const express = require('express');
const router = express.Router();
// Comments Model
const Comment = require('../../models/Comment');
// @route UPDATE api/comments
// @desc Update comment
// @access Public
router.put('/:id', (req, res, next) => {
Comment.findbyId(req.params.id)
.then(comment => comment.update(req.body))
.catch(next);
})
module.exports = router;
//--------CommentActions.js
import axios from 'axios';
import {
GET_COMMENTS,
ADD_COMMENTS,
COMMENTS_LOADING,
GO_COMMENTS,
UPDATE_COMMENTS
} from './types';
export const updateComment = comment => {
return function(dispatch) {
axios
.put(`/api/comments`, comment)
.then(res =>
dispatch({
type: UPDATE_COMMENTS,
payload: comment
})
)
}
}
//--------CommentReducer.js
import {
GET_COMMENTS,
ADD_COMMENTS,
COMMENTS_LOADING,
GO_COMMENTS,
UPDATE_COMMENTS
} from '../actions/types';
const initialState = {
comments: []
}
export default function(state = initialState, action) {
switch(action.type) {
case UPDATE_COMMENTS:
return {
...state,
comments: state.comments.map(comm => comm._id === action.payload._id ? comm.likes = action.payload + 1 : comm.likes)
}
}
}
您需要使用:
Comment.findById()
您对客户端的放置请求需要类似于:
axios.get(`/api/comments/${comment.id}` comment)
我做了一些改动:
- 评论模型“喜欢”变成了一个对象数组,所以我可以存储评论的 ID、喜欢评论的访问者的 ID(将在页面加载时创建,在 localStorage 的帮助下)和单击赞按钮的日期:
models/Comment.js:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// Create Schema
const CommentSchema = new Schema({
likes: [
{
commentId: {
type: String,
required: true
},
userId: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
}
}
],
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
comment: {
type: String,
required: true
},
forWich: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
}
});
module.exports = Comment = mongoose.model('comment', CommentSchema);
- 路由已更改,从“put”更改为“post”,因此我添加了整个对象,而不是连接数字:
routes/api/comments:
router.post('/like', (req, res) => {
const { commentId, userId } = req.body;
Comment.findById(commentId)
.then(comment => {
comment.likes.unshift({ commentId, userId });
comment.save().then(comment => res.json(comment));
})
.catch(err => {
res.status(404).json({ commentnotfound: "No comment found" })
});
});
- Redux 操作,我将“handleLike”更改为“addLike”
actions/commentActions.js:
export const addLike = ({ commentId, userId }) => {
return function(dispatch) {
const config = {
headers: {
'Content-Type': 'application/json'
}
}
const body = JSON.stringify({ commentId, userId });
axios.post(`/api/comments/like`, body, config)
.then(res => {
dispatch(getComments())
}
)
}
};
...如您所见,没有任何负载归因于任何类型,因此不再需要使用 UPDATE_COMMENTS,因此也没有减速器。
- 最后,前端,在页面加载时,我使用 localStorage 将 Id 分配给新客户端。基于该 Id,我正在创建一个新的 like 对象:
PostPage.js:
useEffect(() => {
if (!localStorage.getItem(`userId`)) {
localStorage.setItem(`userId`, uuidv4())
}
}, [])
const handleLike = e => {
e.preventDefault()
if(localStorage.getItem(`userId`)) {
const newLike = {
commentId: e.target.value,
userId: localStorage.getItem(`userId`)
}
dispatch(addLike(newLike))
}
}
我需要从我的 mongodb 数据库“评论”集合中更新我的“评论”对象。更具体地说,当我按下“喜欢”按钮时,我想发送一个带有 axios 的放置请求,我可以在其中将 + 1 添加到“评论”对象的“喜欢”。
所有其他操作都正常(获取评论、添加评论等),我唯一遇到困难的是更新评论赞。
如果有人能提供帮助,我将不胜感激。提前致谢!
我在下面添加了我的代码:
//--------CommentComponent.js
import React, { useState, useEffect } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { getComments, updateComment } from '../actions/commentActions'
const PostPage = ({ match }) => {
const commentz = useSelector(store => store.comment.comments)
const dispatch = useDispatch()
useEffect(() => {
dispatch(getComments())
}, [dispatch])
const handleLike = e => {
dispatch(updateComment(e.target.id))
}
return (
{commentz ? commentz.map(comm =>
comm.forWich === match.params.id ?
<div key={comm._id} className={styles.comment}>
<div>
<h2>{comm.name}</h2>
</div>
<div>
<p>{comm.comment}</p>
</div>
{comm.likes} <button id={comm} onClick={handleLike}>Like</button>
<div>
</div>
: null
) : null}
)
}
export default PostPage
//--------Comment.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// Create Schema
const CommentSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
comment: {
type: String,
required: true
},
forWich: {
type: String,
required: true
},
likes: {
type: Number,
default: 0
},
date: {
type: Date,
default: Date.now
}
});
module.exports = Comment = mongoose.model('comment', CommentSchema);
//--------comments.js
const express = require('express');
const router = express.Router();
// Comments Model
const Comment = require('../../models/Comment');
// @route UPDATE api/comments
// @desc Update comment
// @access Public
router.put('/:id', (req, res, next) => {
Comment.findbyId(req.params.id)
.then(comment => comment.update(req.body))
.catch(next);
})
module.exports = router;
//--------CommentActions.js
import axios from 'axios';
import {
GET_COMMENTS,
ADD_COMMENTS,
COMMENTS_LOADING,
GO_COMMENTS,
UPDATE_COMMENTS
} from './types';
export const updateComment = comment => {
return function(dispatch) {
axios
.put(`/api/comments`, comment)
.then(res =>
dispatch({
type: UPDATE_COMMENTS,
payload: comment
})
)
}
}
//--------CommentReducer.js
import {
GET_COMMENTS,
ADD_COMMENTS,
COMMENTS_LOADING,
GO_COMMENTS,
UPDATE_COMMENTS
} from '../actions/types';
const initialState = {
comments: []
}
export default function(state = initialState, action) {
switch(action.type) {
case UPDATE_COMMENTS:
return {
...state,
comments: state.comments.map(comm => comm._id === action.payload._id ? comm.likes = action.payload + 1 : comm.likes)
}
}
}
您需要使用:
Comment.findById()
您对客户端的放置请求需要类似于:
axios.get(`/api/comments/${comment.id}` comment)
我做了一些改动:
- 评论模型“喜欢”变成了一个对象数组,所以我可以存储评论的 ID、喜欢评论的访问者的 ID(将在页面加载时创建,在 localStorage 的帮助下)和单击赞按钮的日期:
models/Comment.js:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// Create Schema
const CommentSchema = new Schema({
likes: [
{
commentId: {
type: String,
required: true
},
userId: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
}
}
],
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
comment: {
type: String,
required: true
},
forWich: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
}
});
module.exports = Comment = mongoose.model('comment', CommentSchema);
- 路由已更改,从“put”更改为“post”,因此我添加了整个对象,而不是连接数字:
routes/api/comments:
router.post('/like', (req, res) => {
const { commentId, userId } = req.body;
Comment.findById(commentId)
.then(comment => {
comment.likes.unshift({ commentId, userId });
comment.save().then(comment => res.json(comment));
})
.catch(err => {
res.status(404).json({ commentnotfound: "No comment found" })
});
});
- Redux 操作,我将“handleLike”更改为“addLike”
actions/commentActions.js:
export const addLike = ({ commentId, userId }) => {
return function(dispatch) {
const config = {
headers: {
'Content-Type': 'application/json'
}
}
const body = JSON.stringify({ commentId, userId });
axios.post(`/api/comments/like`, body, config)
.then(res => {
dispatch(getComments())
}
)
}
};
...如您所见,没有任何负载归因于任何类型,因此不再需要使用 UPDATE_COMMENTS,因此也没有减速器。
- 最后,前端,在页面加载时,我使用 localStorage 将 Id 分配给新客户端。基于该 Id,我正在创建一个新的 like 对象:
PostPage.js:
useEffect(() => {
if (!localStorage.getItem(`userId`)) {
localStorage.setItem(`userId`, uuidv4())
}
}, [])
const handleLike = e => {
e.preventDefault()
if(localStorage.getItem(`userId`)) {
const newLike = {
commentId: e.target.value,
userId: localStorage.getItem(`userId`)
}
dispatch(addLike(newLike))
}
}