构建 MERN 调查应用程序,第 5 天:后端
我对这个项目的最初计划涉及构建一个更复杂的应用程序,但该项目只是开始学习一些东西,然后再开发一个已经在进行中的不同应用程序,而且我已经意识到,在这个时间点,我需要学习的只有两件事是身份验证和连接前端和后端。我可能会在未来的某个时候回到这个应用程序,但明天很可能会在一段时间内结束这个项目。 今天我将致力于设置后端 API,以便前端可以与数据库进行交互。 第一步是创建一些文件: 然后是一些样板和占位符
我对这个项目的最初计划涉及构建一个更复杂的应用程序,但该项目只是开始学习一些东西,然后再开发一个已经在进行中的不同应用程序,而且我已经意识到,在这个时间点,我需要学习的只有两件事是身份验证和连接前端和后端。我可能会在未来的某个时候回到这个应用程序,但明天很可能会在一段时间内结束这个项目。
今天我将致力于设置后端 API,以便前端可以与数据库进行交互。
第一步是创建一些文件:
然后是一些样板和占位符代码,以确保一切正常:
// server.js
import express from "express";
import bodyParser from "body-parser";
import cors from 'cors';
import { router } from './routes.js';
import dotenv from 'dotenv';
import mongoose from 'mongoose';
dotenv.config();
const app = express();
const port = process.env.PORT;
const user = process.env.DB_USER;
const pass = process.env.DB_PASS;
const cluster = process.env.DB_CLUSTER;
const dbName = process.env.DB_NAME;
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cors());
app.use("/", router);
mongoose.connect(`mongodb+srv://${user}:${pass}@${cluster}.58qh2.mongodb.net/${dbName}?retryWrites=true&w=majority`, {
useNewUrlParser: true
}).then(() => {
console.log("Successfully connected to the database");
}).catch(err => {
console.log('Could not connect to the database. Exiting now...', err);
process.exit();
});
app.listen(port, () => console.log(`Server is running on port ${port}`));
// routes.js
import express from 'express';
import * as api from './api.js';
export const router = express.Router();
router.get('/', (req, res) => res.redirect('/api'));
router.get('/api', api.main);
router.get('/api/all', api.getAll);
// api.js
export const main = (req, res) => {
res.send('main')
}
export const getAll = (req, res) => {
res.send('all')
}
一切正常,是时候设置一个response
模式了。如果这个应用程序更复杂,我需要担心不同的调查有不同的字段,但由于我现在决定只使用一种形式,模型只是将调查数据转换为一组数据库字段.
我正在从表单中删除密码字段。用户身份验证将单独处理,因此这些字段无用。我现在还注释掉文件上传,因为这需要更复杂的处理,我现在不需要知道如何去做。
// models/Response.js
import mongoose from "mongoose";
const responseSchema = new mongoose.Schema({
name: { type: String, required: true },
email: { type: String, required: true },
select: Number,
selectMulti: [Number],
text: String,
choices: String,
check: Boolean
});
export default mongoose.model('Response', responseSchema);
现在控制器发布数据。我添加了一条路线:
// routes.js
...
router.post('/api/add', api.addResponse);
和控制器:
// api.js
...
export const addResponse = async (req, res) => {
const multi = req.body.selectMulti ? req.body.selectMulti.map(Number) : [];
try {
const responseData = new Response({
name: req.body.name,
email: req.body.email,
select: Number(req.body.select),
selectMulti: multi,
text: req.body.text,
choices: req.body.choices,
check: req.body.check === "true"
})
await responseData.save((err) => {
if (err) return console.error(err);
});
res.json({ 'message': 'success' });
}
catch (err) {
console.log(err);
}
}
现在我需要回到前端将其连接到表单:
// Survey.jsx
...
onSubmit={(values, { setSubmitting }) => {
fetch('http://localhost:5000/api/add', {
headers: { 'Content-Type': 'application/json' },
method: 'post',
body: JSON.stringify(values),
})
.then(response => response.json())
.then(data => {
console.log(data)
setSubmitting(false)
})
.catch(err => console.log(err));
}}
...
表单现在已正确连接,但 1) 除了快速禁用提交按钮和2) selectMulti 的数据没有被发送。
第二个是一个简单的遗漏——我没有添加tag={Field}
。
// Survey.jsx
...
<Input
tag={Field}
multiple
id="selectMulti"
name="selectMulti"
as="select"
type="select"
>
...
第一个并不难修复。由于我只是想知道如何在提交表单后处理重定向,所以我没有设置成功消息,我只是重定向到主页。这需要一些搜索,因为 React Router 处理它的方式随着时间的推移发生了变化,并且旧代码不起作用。
// Survey.jsx
...
import { useNavigate } from "react-router-dom";
...
export default function Survey() {
let navigate = useNavigate();
...
onSubmit={(values, { setSubmitting }) => {
...
navigate("/");
}}
...
今天就是这样,明天是身份验证,然后我将退出这个项目,可能会很长一段时间。
更多推荐
所有评论(0)