解决global.food_items非构造函数错误,实现前端表单向MongoDB Atlas上传数据与图片
解决TypeError: global.food_items is not a constructor错误并实现数据上传
问题根源
- 你在数据库连接文件中将
global.food_items赋值为查询返回的食物数据数组(Food.find({})的结果),而非Mongoose的模型构造函数,因此用new global.food_items()实例化会报错——数组无法作为构造函数使用。 - 数据库连接文件的模块导出逻辑混乱:先导出
connectToMongo函数,后续又在函数内执行module.exports = Food,导致模块导出被覆盖,无法正确引入模型。 - 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
相关产品推荐
相关产品推荐

