mongodb TypeError:Cannot read properties of undefined(阅读'length')in Mongoose / Array is undefined / Angela Yu's Web Development Bootcamp Course

rpppsulh  于 2023-05-06  发布在  Go
关注(0)|答案(4)|浏览(501)

我正在做一个浏览器中的todolist从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.stack.imgur.com/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.");
});

The error here
这个错误指向的是 foundItems 数组,奇怪的是它没有定义。该数组的元素存储在MongoDB数据库中,并且必须显示在Web应用程序todolist中。但这并不是因为提到的错误而发生的。如果 foundItems 数组没有任何项(其长度等于零),则当Web应用程序加载到浏览器中时,defaultItems 数组的项将自动添加到列表中。由于“foundItems”数组未定义,应用程序无法执行语句foundItems.length === 0,这将导致错误发生。最后,我提到了这样一个事实,即到MongoDB服务器的连接是功能性的,并且我可以在数据库中存储(在 app.get 方法之外)“defaultItems”数组的项。
我怀着极大的兴趣等待你的答复!

hfsqlsce

hfsqlsce1#

您可能在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);
    });
});
ar7v8xwq

ar7v8xwq2#

所以有几个建议:

  • 添加[mongoose schema][1]
  • 将你的promise链改为async/await对,就像mongoose的文档那样,这样更容易捕获错误
  • 将mongoose连接函数移到listen函数中
  • 不要从'/'重定向,它将无休止地重定向到它自己
  • 创建迁移端点以迁移默认项
  • 使用路由'/items'创建一个新项目(POST '/items')并检索所有项目(GET '/items'),如[RESTful API实践][2]中所述。
  • 记住,对于成功的get,使用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/

ix0qys7i

ix0qys7i3#

这是因为foundItems可能不会一直有数据。您可以添加检查以查看是否定义了foundItems。
在访问长度之前,使用此检查更改if条件。

if(!foundItems || foundItems.length === 0)
hgc7kmma

hgc7kmma4#

我的list.ejs文件:

<%- include("header") -%>
    
      <div class="box" id="heading">
        <h1> <%= listTitle %> </h1>
      </div>
    
      <div class="box">
      <%  newListItems.forEach().then(function(item){  %>
          <div class="item">
            <input type="checkbox">
            <p><%=  item.name  %></p>
          </div>
      <%  });  %>
    
          <form class="item" action="/" method="post">
            <input type="text" name="newItem" placeholder="New Item" autocomplete="off">
            <button type="submit" name="list">+</button>
          </form>
      </div>
    
    <%- include("footer") -%>

我的新的真实的错误(在list.ejs文件中):

TypeError: C:\Diverse\Probleme facultate\Aplicatii Software - Programare\Web Development\todolist-v2-starting-files\todolist-v2-starting-files\views\list.ejs:8
    6| 
    7|   <div class="box">
 >> 8|   <%  newListItems.forEach().then(function(item){  %>
    9|       <div class="item">
    10|         <input type="checkbox">
    11|         <p><%=  item.name  %></p>

undefined is not a function

新的list.ejs文件代码:

<%- include("header") -%>

  <div class="box" id="heading">
    <h1> <%= listTitle %> </h1>
  </div>

  <div class="box">
  <%  newListItems.forEach(item => { %>
      <div class="item">
        <input type="checkbox">
        <p><%=  item.name  %></p>
      </div>
  <%  });  %>

      <form class="item" action="/" method="post">
        <input type="text" name="newItem" placeholder="New Item" autocomplete="off">
        <button type="submit" name="list">+</button>
      </form>
  </div>

<%- include("footer") -%>

现在整个代码工作得很好!浏览器中的Web应用程序正在正确加载!谢谢大家的帮助和建议!

相关问题