node.js - 使用 MERN 向 Mongo 插入数据只存储 ID
问题描述
我刚刚开始使用 MERN,目前正在努力理解为什么 MongoDB 会存储除了生成 ID 之外的任何内容。虽然 API 的状态码在运行应用程序时显示为 200,但数据库存储如下内容:
{
"_id":{"$oid":"613c98f76daf3b1d94cbbe6b"},
"firstName":null,
"lastName":null,
"email":null
}
前端和后端的代码如下:
从中进行 API 调用的 React 组件
export default class TableScreen extends React.Component {
state = {
firstName: '',
lastName: '',
email: '',
isVisible: false,
position: "centre"
}
openDialog = () => {
this.setState((state, props) => ({
isVisible: true
}))
}
closeDialog = () => {
this.setState((state, props) => ({
isVisible: false
}))
}
onChangeFirstName = (e) => {
this.setState({
firstName : e.target.value
})
}
onChangeLastName = (e) => {
this.setState({
lastName : e.target.value
})
}
onChangeEmail = (e) => {
this.setState({
email : e.target.value
})
}
addUser = () => { //This is the api call
const requestOption = {
method: 'POST',
body: JSON.stringify(this.state.firstName, this.state.lastName, this.state.email)
}
fetch("http://localhost:3001/api/add", requestOption)
.then(res => res.json())
.then(data => console.log(data))
}
render() {
return (
<div>
<Button variant="outlined" color="primary" onClick={() => this.openDialog()}>
Add
</Button>
{/* <UserList></UserList> */}
<Dialog open={this.state.isVisible} onClose={() => this.closeDialog()} aria-labelledby="form-dialog-title">
<DialogTitle id="form-dialog-title">Subscribe</DialogTitle>
<DialogContent>
<DialogContentText>
To subscribe to this website, please enter your email address here. We will send updates
occasionally.
</DialogContentText>
<TextField
autoFocus
margin="dense"
id="firstName"
label="First name"
type="email"
fullWidth
onChange={this.onChangeFirstName}
/>
<TextField
margin="dense"
id="lastName"
label="Last name"
type="email"
fullWidth
onChange={this.onChangeLastName}
/>
<TextField
margin="dense"
id="email"
label="Email"
type="email"
fullWidth
onChange={this.onChangeEmail}
/>
</DialogContent>
<DialogActions>
<Button onClick={() => this.closeDialog()} color="primary">
Cancel
</Button>
//The button that invokes the API
<Button onClick={() => this.addUser()} color="primary">
Add
</Button>
</DialogActions>
</Dialog>
</div>
);
}
}
后端:
const express = require('express');
const cors = require('cors');
const app = express();
const mongoDb = require('mongodb');
const MongoClient = mongoDb.MongoClient;
const uri = "mongodb+srv://coolhack069:XzC6N7dOyUeQl8M9@cluster0.kz6v9.mongodb.net/crud?retryWrites=true&w=majority";
const client = new MongoClient(uri, { useNewUrlParser: true, useUnifiedTopology: true });
app.use(cors());
app.use(express.json());
const port = 3001;
app.post('/api/add', (req, res) => {
console.log(req);
// const user = req.body;
const fName = req.body.firstName;
const lName = req.body.lastName;
const email = req.body.email;
client.connect(err => {
if(err) {
throw err;
}
const collection = client.db('crud').collection('data');
// const storeData = user;
const storeData = {"firstName" : fName, "lastName" : lName, "email" : email};
collection.insertOne(storeData, function(err, result) {
res.send(result);
client.close();
});
})
});
app.listen(port, () => {
console.log(`Application listening at http://localhost:${port}`)
});
package.json
档案_
{
"name": "backend",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"cors": "^2.8.5",
"express": "^4.17.1",
"mongodb": "^4.1.1",
"mongoose": "^6.0.5"
}
}
解决方案
问题在于TableScreen
组件中的 API 函数。我在 addUser 方法中修改了 requestOption 对象,方法是添加 aheader
并更改body
a 位。代码片段如下:
addUser = () => { //This is the api call
const requestOption = {
method: 'POST',
headers : {'Content-Type' : 'application/json'},
body: JSON.stringify({firstName: this.state.firstName, lastName : this.state.lastName, email: this.state.email})
}
fetch("http://localhost:3002/api/add", requestOption)
.then(res => res.json())
.then(data => console.log(data))
}
我刚刚意识到我已经定义了后端来处理 JSON 中的数据。app.use(express.json());
是执行此操作的行。因此,后端将期望接收我们希望以相同格式存储的任何数据。因此,我们需要做的第一件事是确保发送的数据采用相同的格式,我们通过定义 headers 键来做到这一点,该键基本上是为了暗示后端它将接收的内容将是 JSON . 然后body
定义密钥以对象格式发送数据。如果您在问题的初始代码中检查这一行,该JSON.stringify
方法看起来body: JSON.stringify(this.state.firstName, this.state.lastName, this.state.email)
是错误的,因为我们没有以后端期望的格式发送数据。所以简单的解决方法是this.state.firstName, this.state.lastName, this.state.email
在一对大括号中添加这一行{}
将其转换为对象,如上面修改后的代码段所示。如果听起来不正确,我会邀请其他人编辑此答案。
PS:这对于 POST 和 PUT 请求都是理想的
推荐阅读
- spring-boot - 如何在 Spring Boot 中使用来自 RabbitMQ 的 XML 消息
- angular - 将 ViewEncapsulation.None 设置为每个组件
- python-3.x - 当我尝试在自定义 tkinter 文本字段中剪切和粘贴时获取 _tkinter.TclError
- php - 个性化客户的 Woocommerce 优惠券代码
- reactjs - Apollo React 嵌套查询和变异
- opencart - 在 opencart 中插入购物车总数作为奖励积分
- angular - webpack 动态移除模块
- list - 在没有数据类型的 kdb 中创建空列表
- c# - 替换单词并删除多余的空格
- visual-studio - Visual Studio 在哪里获取用于查找符号的 DLL 的哈希?