我对这个项目的最初计划涉及构建一个更复杂的应用程序,但该项目只是开始学习一些东西,然后再开发一个已经在进行中的不同应用程序,而且我已经意识到,在这个时间点,我需要学习的只有两件事是身份验证和连接前端和后端。我可能会在未来的某个时候回到这个应用程序,但明天很可能会在一段时间内结束这个项目。

今天我将致力于设置后端 API,以便前端可以与数据库进行交互。

第一步是创建一些文件:项目文件结构:server/文件夹包含server.js、routes.js、api.js和models/文件夹。模型包含 Response.js 和 User.js

然后是一些样板和占位符代码,以确保一切正常:

// 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')
}

终端输出显示服务器和数据库连接成功

开发站点返回'all' http://localhost:5000/api/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));
            }}
...

表格填写数据显示表单数据的 Mongo 数据库条目已成功插入,但 selectMulti 没有数据表单现在已正确连接,但 1) 除了快速禁用提交按钮和2) selectMulti 的数据没有被发送。

第二个是一个简单的遗漏——我没有添加tag={Field}

// Survey.jsx
...
<Input
    tag={Field}
    multiple
    id="selectMulti"
    name="selectMulti"
    as="select"
    type="select"
>
...

表格填写数据显示表单数据的 Mongo 数据库条目已成功插入,selectMulti 有数据

第一个并不难修复。由于我只是想知道如何在提交表单后处理重定向,所以我没有设置成功消息,我只是重定向到主页。这需要一些搜索,因为 React Router 处理它的方式随着时间的推移发生了变化,并且旧代码不起作用。

// Survey.jsx
...
import { useNavigate } from "react-router-dom";
...
export default function Survey() {
    let navigate = useNavigate();
...
            onSubmit={(values, { setSubmitting }) => {
           ...
                navigate("/");
            }}
...

今天就是这样,明天是身份验证,然后我将退出这个项目,可能会很长一段时间。

Logo

MongoDB社区为您提供最前沿的新闻资讯和知识内容

更多推荐