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

使用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')"错误。

错误截图:
Error

我已检查模型导入和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")关联查询,前端完全不需要重复调用模型,属于冗余操作。

修复步骤

  1. 移除前端对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;
    
  2. 额外优化建议

    • User模型中没有name字段,原前端模板的order.user_id.name会报错,需改为order.user_id.email,或在UserSchema中添加name字段。
    • 前端直接暴露/api/secret接口存在安全风险,建议将JWT验证逻辑移至后端,前端仅需传递token,由后端负责解密和身份校验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 02:10:39