开发者问题收集

TypeError:无法读取 Mongoose 中未定义的属性(读取“长度”)/数组未定义/Angela Yu 的 Web 开发训练营课程

2023-05-01
275

我正在根据 Angela Yu 的 Web 开发训练营课程在浏览器中制作待办事项列表。我的问题是,当我尝试从浏览器 ( localhost:3000 ) 启动 Web 应用程序时,我收到错误:

TypeError: Cannot read properties of undefined (reading 'length') 

我的代码是:

//jshint esversion:6

const express = require("express");
const bodyParser = require("body-parser");
const mongoose = require("mongoose");
const app = express();

app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({extended: true}));
app.use(express.static("public"));

mongoose.connect("mongodb://127.0.0.1:27017/todolistDB",
{
  useUnifiedTopology: true,
  useNewUrlParser: true,
  serverSelectionTimeoutMS: 5000
}).catch(err => console.log(err.reason));

  const itemsSchema = {
    name: String
  };

  const Item = mongoose.model("Item", itemsSchema);

  const item1 = new Item({
    name: "Welcome to your todolist!"
  });

  const item2 = new Item({
    name: "Hit the + button to add a new item."
  });

  const item3 = new Item({
    name: "<-- Hit this to delete an item."
  });

  const defaultItems = [item1, item2, item3];

app.get("/", function(req, res) {
  Item.find({}).then(function(err, foundItems){
      if(foundItems.length === 0) {
        Item.insertMany(defaultItems).then(function(err) {
          if(err) {
            console.log(err);
          } else {
            console.log("Successfully saved default items to DB!");
            console.log(defautItems);
          }
        });
        res.redirect("/");
      }
    else {
      res.render("list", {listTitle: "Today", newListItems: foundItems});
      console.log(foundItems);
    }
  });
});

app.post("/", function(req, res){
  const itemName = req.body.newItem;
  const item = new Item({[enter image description here](https://i.sstatic.net/C2viu.png)
    name: itemName
  });
  item.save();
  res.redirect("/");
});

app.get("/work", function(req,res){
  res.render("list", {listTitle: "Work List", newListItems: workItems});
});

app.get("/about", function(req, res){
  res.render("about");
});

app.listen(3000, function() {
  console.log("Server started on port 3000.");
});

错误在这里

错误是指 foundItems 数组,该数组奇怪地未定义。此数组的元素存储在 MongoDB 数据库中,必须显示在 Web 应用程序待办事项列表中。但由于提到的错误,这并没有发生。如果 foundItems 数组没有任何项目(其长度等于零),则在浏览器中加载 Web 应用程序时, defaultItems 数组的项目将自动添加到列表中。由于“foundItems”数组未定义,应用程序无法执行语句 foundItems.length === 0 ,从而导致错误发生。 最后,我要提到一个事实,即与 MongoDB 服务器的连接是有效的,我可以将“defaultItems”数组的项目存储(在 app.get 方法之外)在数据库中。

我非常期待您的答复!

3个回答

您可能在 app.get("/", function(req, res) 函数上收到来自 Mongoose 的另一个错误。如果您稍微更改代码,就会看到真正的错误。因此,请将函数 app.get("/", function(req, res) 替换为:

app.get("/", function (req, res) {
  Item.find({})
    .then(foundItems => {
      if (foundItems.length === 0) {
        Item.insertMany(defaultItems)
          .then(function () {
            console.log("Successfully saved default items to DB!");
            console.log(defaultItems);
            res.redirect("/");
          })
          .catch(function (err) {
            console.log("Error inserting default items:", err);
          });
      } else {
        res.render("list", { listTitle: "Today", newListItems: foundItems });
        console.log(foundItems);
      }
    })
    .catch(err => {
      console.log("Error finding items:", err);
    });
});
hkanjih
2023-05-01

因此,有几条建议:

  • 添加 [mongoose schema][1]
  • 将承诺链更改为 async/await 对,如 mongoose 的文档,这样更容易捕获错误
  • 将 mongoose connect 函数移到 listen 函数中
  • 不要从 '/' 重定向,它会无休止地重定向到自身
  • 创建迁移端点以迁移默认项目
  • 使用路由 '/items' 创建新项目( POST '/items' )并检索所有项目( GET '/items' ),如 [RESTful API 实践][2] 中所述
  • 请记住使用 res.status(200) 来成功获取,使用 res.status(201) 来成功创建项目,并且 res.status(400) 表示错误请求。这些结束了请求。

我的工作版本在这里: https://replit.com/join/ygazhrwuqj-zwiqler94

[1]: https://mongoosejs.com/docs/index.html#:~:text=For%20brevity%2C%20let%27s,Kitten%27%2C%20kittySchema )%3B [2]: https://restfulapi.net/resource-naming/

Zwiqy45
2023-05-01

这是因为 foundItems 可能并非始终都有数据。您可以添加检查以查看 foundItems 是否已定义。

在访问长度之前使用此检查更改您的 if 条件。

if(!foundItems || foundItems.length === 0)
lbstack
2023-05-01