TypeError:无法读取 Mongoose 中未定义的属性(读取“长度”)/数组未定义/Angela Yu 的 Web 开发训练营课程
我正在根据 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 方法之外)在数据库中。
我非常期待您的答复!
您可能在
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);
});
});
因此,有几条建议:
- 添加 [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/
这是因为
foundItems
可能并非始终都有数据。您可以添加检查以查看 foundItems 是否已定义。
在访问长度之前使用此检查更改您的
if
条件。
if(!foundItems || foundItems.length === 0)