为什么我在尝试使用我的模型时会收到错误信息?

huangapple go评论78阅读模式
英文:

why do i get an error when i try to use my models?

问题

我正在使用NextJSMongoose开发一个应用程序。当我尝试从Mongoose中使用我的模型时,我遇到了一个错误,错误消息是:"无法读取null的属性(读取'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;

在前端,我在Next.js的pages文件夹中调用我的数据。

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;
      // 从cookie中获取JWT令牌
      const token = cookie.parse(document.cookie).OursiteJWT;
      const decoded = jwt.verify(token, secret);
      const userId = decoded._id;
      // 从后端API获取用户的订单
      const response = await axios.get(`/api/orders?user_id=${userId}`);
      const orders = response.data;

      // 填充每个订单中的user_id字段与关联的用户对象
      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:

import Order from "../../models/Order";
import { initMongoose } from "../../lib/mongoose";

initMongoose();

export default async function (req, res) {
  // 从查询字符串中获取用户ID
  const userId = req.query.user_id;

  // 查找用户的订单
  const orders = await Order.find({ user_id: userId }).populate("user_id");

  // 将订单作为响应发送
  res.json(orders);
};

api/secret:

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`);
  }
}

希望这可以帮助你解决问题。如果你有任何其他问题,请随时提问。

英文:

I'm developing a NextJS app with Mongoose.

And I get a &quot;Cannot read properties of null (reading &#39;get&#39;)&quot; error when I try to use my models from Mongoose.

Here is a screenshot of the error:


为什么我在尝试使用我的模型时会收到错误信息?


I've checked that I've imported my models correctly and initialized Mongoose correctly, but I can't find the cause of this error.

models/Order.js :

import {model, models, Schema} from &quot;mongoose&quot;;
import mongoose from &#39;mongoose&#39;;

const OrderSchema = new mongoose.Schema({
  products: {
    type: Object,
    required: true,
  },
  user_id: {
    type: mongoose.Schema.Types.ObjectId,
    ref: &quot;User&quot;,
  },
  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(&#39;Order&#39;, OrderSchema)

export default Order;

models/User.js:

import {model, models, Schema} from &quot;mongoose&quot;;

const UserSchema = new Schema( {
  email:{
    type:String,
    required:true,
    unique:true,
  },
  password:{
    type:String,
    required:true,
  }
});

const User = typeof models === &#39;object&#39; ? models.User : model(&#39;User&#39;, UserSchema);

export default User ;

And front side I call my data in pages folder of nextjs
pages/orders.js:

import { useEffect, useState } from &quot;react&quot;;
import axios from &quot;axios&quot;;
import jwt from &quot;jsonwebtoken&quot;;
import cookie from &quot;cookie&quot;;
import Order from &quot;../models/Order&quot;;


function Orders() {
  const [orders, setOrders] = useState([]);
  

  useEffect(() =&gt; {
    async function fetchOrders() {
      const res = await axios.get(&quot;/api/secret&quot;);
      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) =&gt; {
        return await Order.findById(order._id).populate(&quot;user_id&quot;);
      }));

      setOrders(populatedOrders);
    }

    fetchOrders();
  }, []);

  return (
    &lt;div&gt;
      {orders.map((order) =&gt; (
        &lt;div key={order._id}&gt;
          &lt;h2&gt;Commande {order._id}&lt;/h2&gt;
          &lt;p&gt;Utilisateur: {order.user_id.name}&lt;/p&gt;
          &lt;p&gt;Adresse: {order.address}&lt;/p&gt;
          &lt;p&gt;Ville: {order.city}&lt;/p&gt;
          &lt;p&gt;Produits:&lt;/p&gt;
          &lt;ul&gt;
            {order.products.map((product) =&gt; (
              &lt;li key={product._id}&gt;{product.name}&lt;/li&gt;
            ))}
          &lt;/ul&gt;
        &lt;/div&gt;
      ))}
    &lt;/div&gt;
  );
}

export default Orders;

api/orders :

/* eslint-disable import/no-anonymous-default-export */
import Order from &quot;../../models/Order&quot;;
import {initMongoose} from &quot;../../lib/mongoose&quot;;


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(&quot;user_id&quot;);

  // Send the orders as the response
  res.json(orders);
};

api/secret :

export default async function handler(req, res) {
  const { method } = req;

  if (method === &#39;GET&#39;) {
    res.json({ secret: process.env.SECRET });
  } else {
    res.setHeader(&#39;Allow&#39;, [&#39;GET&#39;]);
    res.status(405).end(`Method ${method} Not Allowed`);
  }
}

答案1

得分: 1

以下是翻译好的部分:

订单架构应为 -

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});
英文:

The Order Schema should be -

const OrderSchema = new mongoose.Schema({
products: {
type: Object,
required: true,
},
user_id: {
type: mongoose.Schema.Types.ObjectId,
ref: &quot;User&quot;,
},
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});

答案2

得分: 1

你正在尝试在 Next.js 路由处理程序内创建一个 Express 路由处理程序。请将 api/secret 中的代码重构为以下形式:

export default async function handler(req, res) {
  res.json({ secret: process.env.SECRET })
}

如果您还希望此路由遵循 REST 协议并仅允许接受 GET 请求,您可以使用以下代码:

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`);
  }
}
英文:

You are trying to create an express route handler inside a Next.js route handler. Refactor the code in api/secret to this:

export default async function handler(req, res) {
res.json({ secret: process.env.SECRET })
}

If you also want this route to follow the REST protocol and only allow a GET request to be accepted, you can use the following:

export default async function handler(req, res) {
const { method } = req;
if (method === &#39;GET&#39;) {
res.json({ secret: process.env.SECRET });
} else {
res.setHeader(&#39;Allow&#39;, [&#39;GET&#39;]);
res.status(405).end(`Method ${method} Not Allowed`);
}
}

答案3

得分: 0

mongoose 是服务器端的包。你不能在客户端组件中使用 Order 模型。你可以在服务器端代码中使用模型,包括在 API 函数或 getServerSide 函数中。

英文:

mongoose is server-side package. you cannot use the Order model inside client components. You can use models with server-side code, inside api functions or getServerSide functions.

huangapple
  • 本文由 发表于 2023年1月6日 22:24:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/75032164.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定