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

Node.js电商学习项目删除商品时触发TypeError错误求助

解决删除商品时出现的TypeError: Cannot read property 'price' of undefined问题

看起来你遇到的问题核心是商品删除操作被重复触发了:第一次删除成功后,第二次执行时目标商品已经不存在,导致product变量变成undefined,进而调用Cart.deleteProduct时访问product.price抛出报错。

问题根源拆解

从控制台两次输出Product的结果就能明确:

  • 第一次调用deleteById时,商品还存在,products.find能找到对应对象,正常完成删除并同步购物车操作
  • 第二次调用时,商品已经被删除,products.find返回undefined,这时候尝试访问undefined.price就会触发TypeError

造成重复调用的常见原因:

  • 用户快速重复点击了删除按钮
  • 页面中存在重复的表单元素,导致一次操作提交了两次请求
  • 代码其他逻辑中也调用了Product.deleteById方法

分步解决方案

1. 添加安全校验,避免undefined报错

先在product.js的deleteById方法里增加判断,确保只有找到商品时才执行购物车同步操作,即使重复调用也不会报错:

static deleteById(id, callback) {
  getProductsFromFile(products => {
    const product = products.find(prod => prod.id == id);
    const updatedProducts = products.filter(prod => prod.id !== id);
    fs.writeFile(p, JSON.stringify(updatedProducts), err => {
      if (!err) {
        console.log('Product: ', product);
        // 先判断商品是否存在,再同步删除购物车
        if (product) {
          Cart.deleteProduct(id, product.price, callback);
        } else {
          // 商品已不存在时直接执行回调,终止流程
          callback();
        }
      }
    })
  })
}

2. 修复ID匹配的潜在隐患

你当前用prod.id == id的松散相等判断,如果商品ID是数字类型,但表单提交的productId是字符串(表单输入的value默认都是字符串),可能会出现意外的匹配问题。推荐统一类型后用严格相等===:

// 假设你的商品ID是数字类型,把传入的id转为数字
const targetId = Number(id);
const product = products.find(prod => prod.id === targetId);
const updatedProducts = products.filter(prod => prod.id !== targetId);

3. 前端添加防重复提交逻辑

在products.ejs里给删除按钮添加点击后禁用的逻辑,避免用户重复点击触发多次请求:

<form action="/admin/delete-product" method="POST">
  <input type="hidden" name="productId" value="<%=product.id%>">
  <button class="btn" type="submit" onclick="this.disabled = true; this.form.submit();">Delete</button>
</form>

这样处理后,既解决了当前的报错问题,也能从根源上减少重复触发的情况。

内容的提问来源于stack exchange,提问作者S. Farooq

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:03:34