如何连接表单提交NextJS到MongoDB?

pqwbnv8z  于 2022-11-03  发布在  Go
关注(0)|答案(1)|浏览(252)

我正在学习NextJS,但不知道我需要什么解决方案来链接表单和数据库?在这个任务中,什么钩子更好地与next一起使用?
数据是通过Postman添加的,但我不知道如何与表单连接

我的模型

import { model, models, Schema } from "mongoose";

const productModel = new Schema({
  id: Number,
  wallet: String,
  cover: String,
  title: String,
  description: String,
  url: String,
  price: String,
});

const Products = models.Products || model("Products", productModel);

export default Products;

我的联机

import mongoose from "mongoose";

const connectMongo = async () => {
  try {
    const { connection } = await mongoose.connect(process.env.MONGODB_URI);

    if (connection.readyState === 1) {
      console.log("MongoDB is connected");
    }
  } catch (errors) {
    return Promise.reject(errors);
  }
};

export default connectMongo;

我的控制器

import Products from "../models/productModel";

//POST .../api/product
async function postProduct(req, res) {
  try {
    const formData = req.body;
    if (!formData)
      return res.status(404).json({ error: "Form data isn't provided" });
    Products.create(formData, function (err, data) {
      return res.status(200).json(data);
    });
  } catch (error) {
    return res.status(404).json({ error: "Error while post product" });
  }
}

export {postProduct}

"我的助手"

const BASE_URL = "http://localhost:3000";

//Add new product
export async function postProduct(formData) {
  try {
    const Options = {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(formData),
    };

    const response = await fetch(`${BASE_URL}/api/products`, Options);
    const json = response.json();

    return json;
  } catch (error) {
    return error;
  }
}

我的API

import connectMongo from "../../../database/connection/connectMongo";
import {
  deleteProduct,
  getProducts,
  postProduct,
  putProduct,
} from "../../../database/controllers";

export default function handler(req, res) {
  connectMongo().catch(() =>
    res.status(405).json({ error: "Connection error" })
  );

  //type of request
  const { method } = req;

  switch (method) {
    case "GET":
      getProducts(req, res);
      break;
    case "POST":
      postProduct(req, res);
      break;
    case "PUT":
      putProduct(req, res);
      break;
    case "DELETE":
      deleteProduct(req, res);
      break;
    default:
      res.setHeader("Allow", ["GET", "POST", "PUT", "DELETE"]);
      res.status(405).end(`Method ${method} not allowed `);
      break;
  }
}

我的表单

import NewProductTabs from "./NewProductTabs";
import React from "react";
import { editProduct, postProduct } from "../../../database/helpers/helpers";

export default function NewProductForm() {
  return (
    <div className="flex-col gap-4">
      <NewProductTabs />
      <form
        onSubmit={postProduct}
        action="/api/form"
        method="post"
        className="flex flex-col gap-3 border border-black p-6 pb-10"
      >
        <div className="input-type gap-2">
          <label className="flex px-5 py-2 text-sm font-semibold">
            Cover image
          </label>
          <input
            type="text"
            name="image"
            className="w-full rounded-md border border-black px-5 py-5 text-sm shadow-brutal-sm focus:outline-none"
            placeholder="Image link"
          />
        </div>
        <div className="input-type gap-2">
          <label className="flex px-5 py-2 text-sm font-semibold">Title</label>
          <input
            type="text"
            name="title"
            className="w-full rounded-md border border-black px-5 py-5 text-sm shadow-brutal-sm focus:outline-none"
            placeholder="Title"
          />
        </div>
        <div className="input-type">
          <label className="flex px-5 py-2 text-sm font-semibold">
            About Product
          </label>
          <textarea
            rows="6"
            name="description"
            className="w-full rounded-md border border-black px-5 py-5 text-sm shadow-brutal-sm focus:outline-none"
            placeholder="Description"
          />
        </div>
        <div className="input-type">
          <label className="flex px-5 py-2 text-sm font-semibold">Url</label>
          <input
            type="url"
            name="url"
            className="w-full rounded-md border border-black px-5 py-5 text-sm shadow-brutal-sm focus:outline-none"
            placeholder="/url"
          />
        </div>
        <div className="input-type">
          <label className="flex px-5 py-2 text-sm font-semibold">Price</label>
          <input
            type="number"
            name="price"
            className="w-full rounded-md border border-black px-5 py-5 text-sm shadow-brutal-sm focus:outline-none"
            placeholder="Price, USDT"
          />
        </div>
      </form>
      <footer className="flex h-20">
        <button
          type="submit"
          className="flex w-full place-content-center bg-black p-2 text-sm font-bold"
        >
          <span className="flex items-center text-center text-white">
            {" "}
            Add product{" "}
          </span>
        </button>
      </footer>
    </div>
  );
}

我看过视频,读过文章,但还没有弄清楚需要做什么。

o8x7eapl

o8x7eapl1#

这里可能有几个问题,我建议在前端从获取调用(而不是仅仅返回)中记录console.log错误,以帮助缩小范围。
我首先注意到的是与您的API路线不一致:

  • 在控制器中,将/api/product列为路由
  • 您要发布到/api/products的帮助器函数(注意末尾的**'s**)
  • 表单组件使用/api/form作为操作路由。在这种情况下,您不应该有方法或操作,因为您的onSubmit()方法已经在处理逻辑。如果您确实希望使用本机表单方法,请确保路由正确。

我注意到的另一件大事是,您没有为任何输入赋值。最好在React中创建“受控组件”来跟踪DOM中的输入值变化。请参阅这些docs
在您的案例中,一个基本示例可能如下所示:

class NewProductForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = { imageValue: '', titleValue: '', descriptionValue: '' };

    this.handleTitleChange = this.handleTitleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleTitleChange(event) {
    this.setState({ titleValue: event.target.value });
  }

  async handleSubmit(event) {
    event.preventDefault();
    const response = await postProduct(this.state)
    console.log(response)
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <div className="...">
          <label className="...">Title</label>
          <input
            type="text"
            name="title"
            className="..."
            placeholder="Title"
            value={this.state.titleValue}
            onChange={this.handleTitleChange}
          />
        </div>
      </form>
    );
  }
}

相关问题