javascript 在 Postman 中获取错误“无法读取null的属性(阅读'_id')”

yftpprvb  于 2023-10-14  发布在  Java
关注(0)|答案(1)|浏览(126)

你能帮我解决下面的问题吗?
实际上建立一个电子商务网站,我正在测试一个API的,我遇到下面的错误,而在 Postman 测试。
错误:-"{“错误”:“无法读取null的属性(阅读”_id“)”}”
我迷失了方向,请帮助我。下面是来自不同文件的代码,请仔细阅读并建议需要做哪些更改。
下面是jxt.js

  1. const jwt = require("jsonwebtoken");
  2. const SECRET_KEY = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
  3. const generateToken = (userId) => {
  4. const token = jwt.sign({ userId }, SECRET_KEY, { expiresIn: "48h" });
  5. return token;
  6. };
  7. const getUserIdFromToken = (token) => {
  8. const decodedToken = jwt.verify(token, SECRET_KEY);
  9. return decodedToken.userId;
  10. };
  11. module.exports = { generateToken, getUserIdFromToken };

下面是Authenticate.js

  1. const jwtProvider = require("../config/jwtProvider.js");
  2. const userService = require("../services/user.services.js");
  3. const authenticate = async (req, res, next) => {
  4. try {
  5. const token = req.headers.authorization?.split(" ")[1];
  6. if (!token) {
  7. return res.status(401).send({ error: "Invalid" });
  8. }
  9. const userId = jwtProvider.getUserIdFromToken(token);
  10. const user = userService.findUserById(userId);
  11. if (!user) {
  12. return res.status(401).send({ error: "User not found" });
  13. }
  14. req.user = user;
  15. } catch (error) {
  16. return res.status(500).send({ error: error.message });
  17. }
  18. next();
  19. };
  20. module.exports = authenticate;

下面是orderController.js

  1. const orderService = require("../services/order.services.js");
  2. const createOrder = async (req, res) => {
  3. const user = await req.user;
  4. try {
  5. let createdOrder = await orderService.createOrder(user, req.body);
  6. return res.status(201).send(createdOrder);
  7. } catch (error) {
  8. return res.status(500).send({ error: error.message });
  9. }
  10. };
  11. const findOrderById = async (req, res) => {
  12. const user = await req.user;
  13. try {
  14. let createdOrder = await orderService.findOrderById(req.params.id);
  15. return res.status(201).send(createdOrder);
  16. } catch (error) {
  17. return res.status(500).send({ error: error.message });
  18. }
  19. };
  20. const orderHistory = async (req, res) => {
  21. const user = await req.user;
  22. try {
  23. let createdOrder = await orderService.usersOrderHistory(user._id);
  24. return res.status(201).send(createdOrder);
  25. } catch (error) {
  26. return res.status(500).send({ error: error.message });
  27. }
  28. };
  29. module.exports = {
  30. createOrder,
  31. findOrderById,
  32. orderHistory,
  33. };
  34. "Below is the userController"
  35. const userService = require("../services/user.services.js");
  36. const getUserProfile = async (req, res) => {
  37. try {
  38. const jwt = req.headers.authorization?.split(" ")[1];
  39. if (!jwt) {
  40. return res.status(404).send({ error: "token not found" });
  41. }
  42. const user = await userService.getUserProfileByToken(jwt);
  43. return res.status(200).send(user);
  44. } catch (error) {
  45. return res.status(500).send({ error: error.message });
  46. }
  47. };
  48. const getAllUsers = async (req, res) => {
  49. try {
  50. const users = await userService.getAllUsers();
  51. return res.status(200).send(users);
  52. } catch (error) {
  53. return res.status(500).send({ error: error.message });
  54. }
  55. };
  56. module.exports = { getUserProfile, getAllUsers };
  57. "Below is the User Modal"
  58. const mongoose = require("mongoose");
  59. const userSchema = new mongoose.Schema({
  60. firstName: {
  61. type: String,
  62. required: true,
  63. },
  64. lastName: {
  65. type: String,
  66. required: true,
  67. },
  68. password: {
  69. type: String,
  70. required: true,
  71. },
  72. email: {
  73. type: String,
  74. required: true,
  75. },
  76. role: {
  77. type: String,
  78. required: true,
  79. default: "CUSTOMER",
  80. },
  81. mobile: {
  82. type: String,
  83. },
  84. address: [
  85. {
  86. type: mongoose.Schema.Types.ObjectId,
  87. ref: "addresses",
  88. },
  89. ],
  90. paymentInformation: [
  91. {
  92. type: mongoose.Schema.Types.ObjectId,
  93. ref: "payment_information",
  94. },
  95. ],
  96. ratings: [
  97. {
  98. type: mongoose.Schema.Types.ObjectId,
  99. ref: "ratings",
  100. },
  101. ],
  102. reviews: [
  103. {
  104. type: mongoose.Schema.Types.ObjectId,
  105. ref: "reviews",
  106. },
  107. ],
  108. createdAt: {
  109. type: Date,
  110. default: Date.now(),
  111. },
  112. });
  113. const User = mongoose.model("users", userSchema);
  114. module.exports = User;

下面是orderservices代码

  1. const Address = require("../models/address.model.js");
  2. const Order = require("../models/order.model.js");
  3. const OrderItem = require("../models/orderItems.js");
  4. const cartService = require("../services/cart.services.js");
  5. async function createOrder(user, shipAddress) {
  6. let address;
  7. if (shipAddress._id) {
  8. let existAddress = await Address.findById(shipAddress._id);
  9. address = existAddress;
  10. } else {
  11. address = new Address(shipAddress);
  12. address.user = user;
  13. await address.save();
  14. console.error(address);
  15. user.address.push(address);
  16. await user.save();
  17. }
  18. const cart = await cartService.findUserCart(user._id);
  19. const orderItems = [];
  20. for (const item of cart.cartItems) {
  21. const orderItem = new OrderItem({
  22. price: item.price,
  23. product: item.product,
  24. quantity: item.quantity,
  25. size: item.size,
  26. userId: item.userId,
  27. discountedPrice: item.discountedPrice,
  28. });
  29. const createdOrderItem = await orderItem.save();
  30. orderItems.push(createdOrderItem);
  31. }
  32. const createdOrder = new Order({
  33. user,
  34. orderItems,
  35. totalPrice: cart.totalPrice,
  36. totalDiscountedPrice: cart.totalDiscountedPrice,
  37. discount: cart.discount,
  38. totalItem: cart.totalItem,
  39. shipAddress: address,
  40. });
  41. const savedOrder = await createdOrder.save();
  42. return savedOrder;
  43. }
  44. async function placeOrder(orderId) {
  45. const order = await findOrderById(orderId);
  46. order.orderStatus = "PLACED";
  47. order.paymentDetails.status = "COMPLETED";
  48. return await order.save();
  49. }
  50. async function confirmedOrder(orderId) {
  51. const order = await findOrderById(orderId);
  52. order.orderStatus = "CONFIRMED";
  53. return await order.save();
  54. }
  55. async function shippedOrder(orderId) {
  56. const order = await findOrderById(orderId);
  57. order.orderStatus = "SHIPPED";
  58. return await order.save();
  59. }
  60. async function deliveredOrder(orderId) {
  61. const order = await findOrderById(orderId);
  62. order.orderStatus = "DELIVERED";
  63. return await order.save();
  64. }
  65. async function cancelledOrder(orderId) {
  66. const order = await findOrderById(orderId);
  67. order.orderStatus = "CANCELLED";
  68. return await order.save();
  69. }
  70. async function findOrderById(orderId) {
  71. const order = await Order.findById(orderId)
  72. .populate("user")
  73. .populate({ path: "orderItems", populate: { path: "product" } })
  74. .populate("shippingAddress");
  75. return order;
  76. }
  77. async function usersOrderHistory(userId) {
  78. try {
  79. const orders = await Order.find({
  80. user: userId,
  81. orderStatus: "PLACED",
  82. })
  83. .populate({ path: "orderItems", populate: { path: "product" } })
  84. .lean();
  85. return orders;
  86. } catch (error) {
  87. throw new Error(error.message);
  88. }
  89. }
  90. async function getAllOrders() {
  91. return await Order.find()
  92. .populate({ path: "orderItems", populate: { path: "product" } })
  93. .lean();
  94. }
  95. async function deleteOrder(orderId) {
  96. const order = await findOrderById(orderId);
  97. await Order.findByIdAndDelete(order._id);
  98. }
  99. module.exports = {
  100. createOrder,
  101. placeOrder,
  102. confirmedOrder,
  103. shippedOrder,
  104. deliveredOrder,
  105. cancelledOrder,
  106. findOrderById,
  107. usersOrderHistory,
  108. getAllOrders,
  109. deleteOrder,
  110. };
  111. Below is the userServices code
  112. const User = require("../models/user.model");
  113. const bcrypt = require("bcrypt");
  114. const jwtProvider = require("../config/jwtProvider.js");
  115. const createUser = async (userData) => {
  116. try {
  117. let { firstName, lastName, email, password } = userData;
  118. const isUserExist = await User.findOne({ email });
  119. if (isUserExist) {
  120. throw new Error(
  121. `Sorry, but a user with email address: ${email} already exists. Please use a different email.`
  122. );
  123. }
  124. password = await bcrypt.hash(password, 8);
  125. const user = await User.create({ firstName, lastName, email, password });
  126. console.log("create user", user);
  127. return user;
  128. } catch (error) {
  129. throw new Error(error.message);
  130. }
  131. };
  132. const findUserById = async (userId) => {
  133. try {
  134. const user = await User.findById(userId).populate("address");
  135. if (!user) {
  136. throw new Error(
  137. `User not found with userId ${userId}. Please check your user ID and try again.`
  138. );
  139. }
  140. return user;
  141. } catch (error) {
  142. throw new Error(error.message);
  143. }
  144. };
  145. const getUserByEmail = async (email) => {
  146. try {
  147. const user = await User.findOne({ email });
  148. if (!user) {
  149. throw new Error(
  150. `User not found with email ${email}. Please check your email ID and try again.`
  151. );
  152. }
  153. return user;
  154. } catch (error) {
  155. throw new Error(error.message);
  156. }
  157. };
  158. const getUserProfileByToken = async (token) => {
  159. try {
  160. const userId = jwtProvider.getUserIdFromToken(token);
  161. const user = await findUserById(userId);
  162. if (!user) {
  163. throw new Error(
  164. `User not found with userId ${userId}. Please check your email ID and try again.`
  165. );
  166. }
  167. return user;
  168. } catch (error) {
  169. throw new Error(error.message);
  170. }
  171. };
  172. const getAllUsers = async () => {
  173. try {
  174. const users = await User.find();
  175. return users;
  176. } catch (error) {
  177. throw new Error(error.message);
  178. }
  179. };
  180. module.exports = {
  181. createUser,
  182. findUserById,
  183. getUserByEmail,
  184. getUserProfileByToken,
  185. getAllUsers,
  186. };

试着找出错误。没有尝试任何不同的东西

mspsb9vt

mspsb9vt1#

不需要太仔细地观察,您应该能够在包含_id的对象上使用安全导航器。我怀疑这个问题源于:

  1. let createdOrder = await orderService.usersOrderHistory(user._id);

因为这似乎是您定义错误响应格式的地方。但是,在尝试访问null对象的_id时,以下所有内容都可能引发类似的问题。

  1. if (shipAddress._id) {
  1. const cart = await cartService.findUserCart(user._id);
  1. await Order.findByIdAndDelete(order._id);

一个简单的修复方法是添加JS的安全对象访问器/导航器?。范例:

  1. let createdOrder = await orderService.usersOrderHistory(user?._id);

但是,请注意,如果无论什么处理结果(在这种情况下:usersOrderHistory)如果无法处理null值,则可能会引发问题。
另一种选择是创建一个if保护,以应对_id的对象可能为空的情况:

  1. if (user) {
  2. ...
  3. let createdOrder = await orderService.usersOrderHistory(user?._id);
  4. ...
  5. }

(虽然对于这种情况不一定值得,但我倾向于将lodash包/库用于许多与对象相关的操作。有了这个,你可以做:

  1. import _ from 'lodash';
  2. ...
  3. // a default value is not 100% necessary, but if `user` does not have
  4. // `_id` for whatever reason, then this will return `undefined`
  5. const someDefaultValue = -1;
  6. let createdOrder = await orderService.usersOrderHistory(_.get(user, '_id', someDefaultValue);
  7. ...

展开查看全部

相关问题