You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解决global.food_items非构造函数错误,实现前端表单向MongoDB Atlas上传数据与图片

解决TypeError: global.food_items is not a constructor错误并实现数据上传

问题根源

  1. 你在数据库连接文件中将global.food_items赋值为查询返回的食物数据数组(Food.find({})的结果),而非Mongoose的模型构造函数,因此用new global.food_items()实例化会报错——数组无法作为构造函数使用。
  2. 数据库连接文件的模块导出逻辑混乱:先导出connectToMongo函数,后续又在函数内执行module.exports = Food,导致模块导出被覆盖,无法正确引入模型。
  3. AddItem.js中错误注释了模型引入代码,转而依赖全局变量创建新文档,进一步加剧了问题。

具体解决步骤

步骤1:重构数据库文件,拆分模型定义与连接逻辑

将Mongoose模型单独定义,确保可被正确引入,同时保留数据库连接与全局变量赋值逻辑。修改后的db.js:

const mongoose = require('mongoose');
const pass = 'mongodb+srv://Admin:Admin0202@cluster0.ydoby6v.mongodb.net/mern_website_burger_bro';

// 定义食物模型
const foodSchema = new mongoose.Schema({
  CategoryName: String,
  name: String,
  img: String,
  options: [{
    medium: String,
    large: String,
  }],
  description: String
});
const Food = mongoose.model('food_items', foodSchema);

// 定义分类模型
const categorySchema = new mongoose.Schema({
  CategoryName: String,
});
const Category = mongoose.model('food_categories', categorySchema);

// 数据库连接函数
const connectToMongo = async () => {
  try {
    mongoose.set('strictQuery', false);
    await mongoose.connect(pass);
    console.log('Connected to MongoDB successfully!');

    // 查询数据并赋值给全局变量(仅用于读取现有数据)
    try {
      const foodItems = await Food.find({});
      global.food_items = foodItems;
    } catch (foodError) {
      console.log('Error fetching food items:', foodError);
    }
    try {
      const categories = await Category.find({});
      global.food_category = categories;
    } catch (categoryError) {
      console.log('Error fetching food categories:', categoryError);
    }
  } catch (error) {
    console.log('MongoDB connection error:', error);
  }
};

// 导出连接函数和模型
module.exports = { connectToMongo, Food, Category };

步骤2:修正AddItem.js的模型引入与文档创建逻辑

取消模型引入的注释,使用正确的Food模型创建新文档,不再依赖全局变量。修改后的AddItem.js:

// imports at the top
const express = require('express');
const router = express.Router();
const multer = require('multer');
const { Food } = require("../db"); // 引入Food模型
const path = require('path');
const fs = require('fs');

// Multer configuration
const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    const uploadPath = path.resolve(__dirname, 'uploads');
    // 自动创建不存在的上传目录
    if (!fs.existsSync(uploadPath)) {
      fs.mkdirSync(uploadPath, { recursive: true });
    }
    cb(null, uploadPath);
  },
  filename: (req, file, cb) => {
    const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9);
    const extension = path.extname(file.originalname);
    cb(null, uniqueSuffix + extension);
  }
});
const upload = multer({ storage });

// Route handling function
const uploadFoodItem = async (req, res) => {
  try {
    const formData = req.body;
    // 使用Food模型创建新文档
    const newFoodItem = new Food({
      CategoryName: formData.CategoryName,
      name: formData.name,
      img: req.file.filename, // 存储生成的文件名
      options: [{ medium: formData.price1, large: formData.price2 }],
      description: formData.description
    });
    const savedFoodItem = await newFoodItem.save();
    console.log('Food item saved:', savedFoodItem);
    // 可选:更新全局变量中的食物数据,保证实时性
    global.food_items.push(savedFoodItem);
    res.status(200).json({ message: 'Food item saved successfully' });
  } catch (error) {
    console.log('Error saving food item:', error);
    res.status(500).json({ error: 'Failed to save food item' });
  }
};

// Route definition
router.post('/upload', upload.single('image'), uploadFoodItem);

module.exports = router;

步骤3:确保项目启动时先连接数据库

在主文件(如app.js)中先调用连接函数:

const { connectToMongo } = require('./db');
connectToMongo();

内容的提问来源于stack exchange,提问作者nisha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 13:36:02