使用Mongoose模型时出现Cannot read properties of null错误求助
问题:NextJS + Mongoose 应用出现 "Cannot read properties of null (reading 'get')" 错误
我正在开发一个基于NextJS和Mongoose的应用,当尝试使用Mongoose模型时,出现了"Cannot read properties of null (reading 'get')"错误。
错误截图:
我已检查模型导入和Mongoose初始化是否正确,但仍未找到错误原因。
相关代码如下:
models/Order.js
import {model, models, Schema} from "mongoose"; import mongoose from 'mongoose'; const OrderSchema = new mongoose.Schema({ products: { type: Object, required: true, }, user_id: { type: mongoose.Schema.Types.ObjectId, ref: "User", }, name: { type: String, required: true, }, email: { type: String, required: true, }, address: { type: String, required: true, }, city: { type: String, required: true, }, paid: { type: Number, default: 0 }, }, {timestamps: true}); const Order = models?.Order || model('Order', OrderSchema) export default Order;
models/User.js
import {model, models, Schema} from "mongoose"; const UserSchema = new Schema( { email:{ type:String, required:true, unique:true, }, password:{ type:String, required:true, } }); const User = typeof models === 'object' ? models.User : model('User', UserSchema); export default User ;
pages/orders.js
import { useEffect, useState } from "react"; import axios from "axios"; import jwt from "jsonwebtoken"; import cookie from "cookie"; import Order from "../models/Order"; function Orders() { const [orders, setOrders] = useState([]); useEffect(() => { async function fetchOrders() { const res = await axios.get("/api/secret"); const secret = res.data.secret; // Get the JWT token from the cookies const token = cookie.parse(document.cookie).OursiteJWT; const decoded = jwt.verify(token, secret); const userId = decoded._id // Fetch the orders for the user from the backend API const response = await axios.get(`/api/orders?user_id=${userId}`); const orders = response.data; // Populate the user_id field in each order with the associated user object const populatedOrders = await Promise.all(orders.map(async (order) => { return await Order.findById(order._id).populate("user_id"); })); setOrders(populatedOrders); } fetchOrders(); }, []); return ( <div> {orders.map((order) => ( <div key={order._id}> <h2>Commande {order._id}</h2> <p>Utilisateur: {order.user_id.name}</p> <p>Adresse: {order.address}</p> <p>Ville: {order.city}</p> <p>Produits:</p> <ul> {order.products.map((product) => ( <li key={product._id}>{product.name}</li> ))} </ul> </div> ))} </div> ); } export default Orders;
api/orders.js
/* eslint-disable import/no-anonymous-default-export */ import Order from "../../models/Order"; import {initMongoose} from "../../lib/mongoose"; initMongoose() export default async function(req, res) { // Get the user ID from the query string const userId = req.query.user_id; // Find the orders for the user const orders = await Order.find({ user_id: userId }).populate("user_id"); // Send the orders as the response res.json(orders); };
api/secret.js
export default async function handler(req, res) { const { method } = req; if (method === 'GET') { res.json({ secret: process.env.SECRET }); } else { res.setHeader('Allow', ['GET']); res.status(405).end(`Method ${method} Not Allowed`); } }
解决方案
问题根源
你在前端页面pages/orders.js中直接导入并调用了Mongoose模型Order——Mongoose是Node.js后端专属库,无法在浏览器环境中运行,这会导致模型初始化失败,进而抛出Cannot read properties of null (reading 'get')错误。
另外,你的api/orders接口已经完成了populate("user_id")关联查询,前端完全不需要重复调用模型,属于冗余操作。
修复步骤
移除前端对Mongoose模型的依赖
修改pages/orders.js,删除模型导入和前端查询逻辑,直接使用接口返回的已关联数据:import { useEffect, useState } from "react"; import axios from "axios"; import jwt from "jsonwebtoken"; import cookie from "cookie"; function Orders() { const [orders, setOrders] = useState([]); useEffect(() => { async function fetchOrders() { const res = await axios.get("/api/secret"); const secret = res.data.secret; const token = cookie.parse(document.cookie).OursiteJWT; const decoded = jwt.verify(token, secret); const userId = decoded._id; // 直接使用后端返回的已关联用户的订单数据 const response = await axios.get(`/api/orders?user_id=${userId}`); setOrders(response.data); } fetchOrders(); }, []); return ( <div> {orders.map((order) => ( <div key={order._id}> <h2>订单 {order._id}</h2> {/* User模型无name字段,改为显示email或在UserSchema中添加name字段 */} <p>用户: {order.user_id.email}</p> <p>地址: {order.address}</p> <p>城市: {order.city}</p> <p>商品:</p> <ul> {order.products.map((product) => ( <li key={product._id}>{product.name}</li> ))} </ul> </div> ))} </div> ); } export default Orders;额外优化建议
- User模型中没有
name字段,原前端模板的order.user_id.name会报错,需改为order.user_id.email,或在UserSchema中添加name字段。 - 前端直接暴露
/api/secret接口存在安全风险,建议将JWT验证逻辑移至后端,前端仅需传递token,由后端负责解密和身份校验。
- User模型中没有
内容的提问来源于stack exchange,提问作者Rip Rip
相关产品推荐
相关产品推荐

