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

Express+MongoDB待办列表项目:app.post方法else分支出现Cannot read properties of null (reading 'items')错误求助

解决Express+Mongoose待办项目中的Cannot read properties of null (reading 'items')错误

我看到你被困在这个错误里快一天了,咱们来一步步拆解问题并解决它。

错误根源分析

你遇到的TypeError: Cannot read properties of null (reading 'items'),本质是在app.post("/")的else分支中,List.findOne({name: listName})返回了null,但你直接尝试访问foundList.items导致的。这种情况通常发生在三种场景:

  • 查询的列表名在数据库中不存在
  • 数据库查询过程中出现了未处理的错误
  • 一个容易忽略的细节:你的表单提交的列表名可能带有多余空格,和数据库中存储的名称不匹配

分步修复方案

1. 先修复EJS表单中的隐藏BUG

打开你的list.ejs,找到提交新项的表单按钮:

<button type="submit" name="list" value="<%= listTitle %> ">+</button>

注意value="<%= listTitle %> "里%>后面的多余空格!这会导致提交的listName带有末尾空格(比如本来是"Work",提交后变成"Work "),数据库中找不到对应的列表,最终foundList为null。

把它改成:

<button type="submit" name="list" value="<%= listTitle %>">+</button>

2. 为POST路由添加错误处理和存在性检查

修改app.js中app.post("/")的else分支,添加错误处理和foundList的存在性判断:

app.post("/", function(req, res){
  const itemName = req.body.newItem;
  const listName = req.body.list;

  const item = new Item({
    name: itemName
  });

  if (listName === "Today"){
    item.save();
    res.redirect("/");
  } else {
    List.findOne({name: listName}, function(err, foundList){
      // 第一步:处理数据库查询错误
      if (err) {
        console.error("查询列表时出错:", err);
        return res.redirect("/"); // 出错时重定向到首页
      }
      // 第二步:检查是否找到目标列表
      if (!foundList) {
        console.log(`未找到名为'${listName}'的列表`);
        // 可选:和GET路由逻辑一致,自动创建不存在的列表
        const newList = new List({
          name: listName,
          items: [item]
        });
        newList.save(function(saveErr) {
          if (!saveErr) res.redirect("/" + listName);
        });
        return;
      }
      // 第三步:一切正常时添加项并保存
      foundList.items.push(item);
      foundList.save(function(saveErr) {
        if (saveErr) {
          console.error("保存项到列表时出错:", saveErr);
        } else {
          res.redirect("/" + listName);
        }
      });
    });
  }
});

3. 可选:改用Async/Await简化代码(推荐)

回调嵌套容易导致错误遗漏,改用Mongoose支持的async/await语法,代码会更清晰,错误处理也更集中:

app.post("/", async function(req, res){
  const itemName = req.body.newItem;
  const listName = req.body.list;

  const item = new Item({
    name: itemName
  });

  try {
    if (listName === "Today"){
      await item.save();
      res.redirect("/");
    } else {
      let foundList = await List.findOne({name: listName});
      if (!foundList) {
        // 自动创建不存在的列表
        foundList = new List({
          name: listName,
          items: [item]
        });
      } else {
        foundList.items.push(item);
      }
      await foundList.save();
      res.redirect("/" + listName);
    }
  } catch (err) {
    console.error("处理POST请求时出错:", err);
    res.redirect("/");
  }
});

验证修复效果

  1. 重启你的Express服务器
  2. 尝试添加新项到自定义列表,比如"/Work"
  3. 如果之前存在不存在的列表名提交,现在要么会自动创建列表,要么会友好地重定向到首页,不会再抛出Cannot read properties of null错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 20:12:28