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

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

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

const jwt = require("jsonwebtoken");

const SECRET_KEY = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
const generateToken = (userId) => {
  const token = jwt.sign({ userId }, SECRET_KEY, { expiresIn: "48h" });
  return token;
};

const getUserIdFromToken = (token) => {
  const decodedToken = jwt.verify(token, SECRET_KEY);
  return decodedToken.userId;
};

module.exports = { generateToken, getUserIdFromToken };

下面是Authenticate.js

const jwtProvider = require("../config/jwtProvider.js");
const userService = require("../services/user.services.js");

const authenticate = async (req, res, next) => {
  try {
    const token = req.headers.authorization?.split(" ")[1];
    if (!token) {
      return res.status(401).send({ error: "Invalid" });
    }

    const userId = jwtProvider.getUserIdFromToken(token);
    const user = userService.findUserById(userId);

    if (!user) {
      return res.status(401).send({ error: "User not found" });
    }
    req.user = user;
  } catch (error) {
    return res.status(500).send({ error: error.message });
  }

  next();
};

module.exports = authenticate;

下面是orderController.js

const orderService = require("../services/order.services.js");

const createOrder = async (req, res) => {
  const user = await req.user;
  try {
    let createdOrder = await orderService.createOrder(user, req.body);
    return res.status(201).send(createdOrder);
  } catch (error) {
    return res.status(500).send({ error: error.message });
  }
};

const findOrderById = async (req, res) => {
  const user = await req.user;
  try {
    let createdOrder = await orderService.findOrderById(req.params.id);
    return res.status(201).send(createdOrder);
  } catch (error) {
    return res.status(500).send({ error: error.message });
  }
};

const orderHistory = async (req, res) => {
  const user = await req.user;
  try {
    let createdOrder = await orderService.usersOrderHistory(user._id);
    return res.status(201).send(createdOrder);
  } catch (error) {
    return res.status(500).send({ error: error.message });
  }
};

module.exports = {
  createOrder,
  findOrderById,
  orderHistory,
};

"Below is the userController"

const userService = require("../services/user.services.js");

const getUserProfile = async (req, res) => {
  try {
    const jwt = req.headers.authorization?.split(" ")[1];

    if (!jwt) {
      return res.status(404).send({ error: "token not found" });
    }
    const user = await userService.getUserProfileByToken(jwt);
    return res.status(200).send(user);
  } catch (error) {
    return res.status(500).send({ error: error.message });
  }
};

const getAllUsers = async (req, res) => {
  try {
    const users = await userService.getAllUsers();
    return res.status(200).send(users);
  } catch (error) {
    return res.status(500).send({ error: error.message });
  }
};

module.exports = { getUserProfile, getAllUsers };

"Below is the User Modal"

const mongoose = require("mongoose");
const userSchema = new mongoose.Schema({
  firstName: {
    type: String,
    required: true,
  },
  lastName: {
    type: String,
    required: true,
  },

  password: {
    type: String,
    required: true,
  },

  email: {
    type: String,
    required: true,
  },
  role: {
    type: String,
    required: true,
    default: "CUSTOMER",
  },

  mobile: {
    type: String,
  },

  address: [
    {
      type: mongoose.Schema.Types.ObjectId,
      ref: "addresses",
    },
  ],

  paymentInformation: [
    {
      type: mongoose.Schema.Types.ObjectId,
      ref: "payment_information",
    },
  ],

  ratings: [
    {
      type: mongoose.Schema.Types.ObjectId,
      ref: "ratings",
    },
  ],
  reviews: [
    {
      type: mongoose.Schema.Types.ObjectId,
      ref: "reviews",
    },
  ],

  createdAt: {
    type: Date,
    default: Date.now(),
  },
});

const User = mongoose.model("users", userSchema);
module.exports = User;

下面是orderservices代码

const Address = require("../models/address.model.js");
const Order = require("../models/order.model.js");
const OrderItem = require("../models/orderItems.js");
const cartService = require("../services/cart.services.js");

async function createOrder(user, shipAddress) {
  let address;
  if (shipAddress._id) {
    let existAddress = await Address.findById(shipAddress._id);
    address = existAddress;
  } else {
    address = new Address(shipAddress);
    address.user = user;
    await address.save();

    console.error(address);

    user.address.push(address);
    await user.save();
  }

  const cart = await cartService.findUserCart(user._id);
  const orderItems = [];

  for (const item of cart.cartItems) {
    const orderItem = new OrderItem({
      price: item.price,
      product: item.product,
      quantity: item.quantity,
      size: item.size,
      userId: item.userId,
      discountedPrice: item.discountedPrice,
    });
    const createdOrderItem = await orderItem.save();
    orderItems.push(createdOrderItem);
  }

  const createdOrder = new Order({
    user,
    orderItems,
    totalPrice: cart.totalPrice,
    totalDiscountedPrice: cart.totalDiscountedPrice,
    discount: cart.discount,
    totalItem: cart.totalItem,
    shipAddress: address,
  });

  const savedOrder = await createdOrder.save();
  return savedOrder;
}
async function placeOrder(orderId) {
  const order = await findOrderById(orderId);
  order.orderStatus = "PLACED";
  order.paymentDetails.status = "COMPLETED";

  return await order.save();
}

async function confirmedOrder(orderId) {
  const order = await findOrderById(orderId);
  order.orderStatus = "CONFIRMED";
  return await order.save();
}

async function shippedOrder(orderId) {
  const order = await findOrderById(orderId);
  order.orderStatus = "SHIPPED";
  return await order.save();
}

async function deliveredOrder(orderId) {
  const order = await findOrderById(orderId);
  order.orderStatus = "DELIVERED";
  return await order.save();
}

async function cancelledOrder(orderId) {
  const order = await findOrderById(orderId);
  order.orderStatus = "CANCELLED";
  return await order.save();
}

async function findOrderById(orderId) {
  const order = await Order.findById(orderId)
    .populate("user")
    .populate({ path: "orderItems", populate: { path: "product" } })
    .populate("shippingAddress");

  return order;
}

async function usersOrderHistory(userId) {
  try {
    const orders = await Order.find({
      user: userId,
      orderStatus: "PLACED",
    })
      .populate({ path: "orderItems", populate: { path: "product" } })
      .lean();
    return orders;
  } catch (error) {
    throw new Error(error.message);
  }
}

async function getAllOrders() {
  return await Order.find()
    .populate({ path: "orderItems", populate: { path: "product" } })
    .lean();
}

async function deleteOrder(orderId) {
  const order = await findOrderById(orderId);
  await Order.findByIdAndDelete(order._id);
}

module.exports = {
  createOrder,
  placeOrder,
  confirmedOrder,
  shippedOrder,
  deliveredOrder,
  cancelledOrder,
  findOrderById,
  usersOrderHistory,
  getAllOrders,
  deleteOrder,
};

Below is the userServices code 

const User = require("../models/user.model");
const bcrypt = require("bcrypt");
const jwtProvider = require("../config/jwtProvider.js");

const createUser = async (userData) => {
  try {
    let { firstName, lastName, email, password } = userData;
    const isUserExist = await User.findOne({ email });
    if (isUserExist) {
      throw new Error(
        `Sorry, but a user with  email address: ${email} already exists. Please use a different email.`
      );
    }
    password = await bcrypt.hash(password, 8);

    const user = await User.create({ firstName, lastName, email, password });

    console.log("create user", user);
    return user;
  } catch (error) {
    throw new Error(error.message);
  }
};

const findUserById = async (userId) => {
  try {
    const user = await User.findById(userId).populate("address");
    if (!user) {
      throw new Error(
        `User not found with userId ${userId}. Please check your user ID and try again.`
      );
    }
    return user;
  } catch (error) {
    throw new Error(error.message);
  }
};

const getUserByEmail = async (email) => {
  try {
    const user = await User.findOne({ email });
    if (!user) {
      throw new Error(
        `User not found with email ${email}. Please check your email ID and try again.`
      );
    }
    return user;
  } catch (error) {
    throw new Error(error.message);
  }
};

const getUserProfileByToken = async (token) => {
  try {
    const userId = jwtProvider.getUserIdFromToken(token);

    const user = await findUserById(userId);

    if (!user) {
      throw new Error(
        `User not found with userId ${userId}. Please check your email ID and try again.`
      );
    }
    return user;
  } catch (error) {
    throw new Error(error.message);
  }
};

const getAllUsers = async () => {
  try {
    const users = await User.find();
    return users;
  } catch (error) {
    throw new Error(error.message);
  }
};
module.exports = {
  createUser,
  findUserById,
  getUserByEmail,
  getUserProfileByToken,
  getAllUsers,
};

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

mspsb9vt

mspsb9vt1#

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

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

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

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

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

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

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

if (user) {
  ...
  let createdOrder = await orderService.usersOrderHistory(user?._id);
  ...
}

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

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

相关问题