TypeError:无法使用nodejs在mongodb中读取null的属性“项目”

Posted

技术标签:

【中文标题】TypeError:无法使用nodejs在mongodb中读取null的属性“项目”【英文标题】:TypeError: Cannot read property 'items' of null in monogdb using nodejs 【发布时间】:2020-09-11 23:49:16 【问题描述】:

我正在创建一个待办事项列表应用程序,它动态添加项目并通过 url 动态创建列表。例如:http://localhost:3000/Home 将创建一个“Home”列表,http://localhost:3000/Work 将创建“Work”并预先添加一些默认值。但是当我通过 url 像:http://localhost:3000/Home 并添加新项目时,它会引发错误。

下面是我的 app.js 代码

//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://localhost:27017/todolistDB", useNewUrlParser:true , useUnifiedTopology: true );
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 new item"
);

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

const defaultItems=[item1,item2,item3];

const listSchema=
  name:String,
  items:[itemsSchema]
;

const List=mongoose.model("List",listSchema);



app.get("/", function(req, res) 

  // finding elements using mongoose and to check if array is empty then add items.
  // if array already contains items then array does not add same items again when starting server mupltipe times.

  Item.find(,function(err,foundItems)
    if (foundItems.length===0) 
      Item.insertMany(defaultItems,function(err)
        if (err) 
          console.log(err);
         else 
          console.log("Saved Successfully.....");
        
      );
      res.redirect("/");
     else 
      res.render("list", listTitle: "Today", newListItems: foundItems);
    
  );




);

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)
      foundList.items.push(item); **// NODE SHELL SHOWING ERROR IN THIS LINE**
      foundList.save();
      res.redirect("/"+listName);
    );
  


);

app.post("/delete",function(req,res)
  const checkedItemId=(req.body.checkbox);
  Item.findByIdAndRemove(checkedItemId,function(err)
    if (err) 
      console.log(err);
     else 
      console.log("Selected item deleted successfully");
      res.redirect("/");
    
  );
);

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

app.get("/:customListName",function(req,res)
  const customListName=req.params.customListName;
  console.log(customListName);
  List.findOne(name:customListName,function(err,foundList)
    if(!err)
      if(!foundList)
        // create a new list
        const list=new List(
          name:customListName,
          items: defaultItems
        );
        list.save();
        res.redirect("/"+customListName);
      
      else
        // show an existing list
        res.render("list",listTitle:foundList.name,newListItems:foundList.items);
      
    
    );


);

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

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

list.ejs 的代码

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

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

  <div class="box">
    <% newListItems.forEach(function(itemName) %>
      <form action="/delete" method="post">


      <div class="item">
        <input type="checkbox" name="checkbox" value="<%= itemName.id %>" onChange="this.form.submit()">
        <p><%=  itemName.name  %></p>
      </div>
      </form>
      <% ) %>

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

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

有什么解决办法吗?

【问题讨论】:

你能提供const a =await List.findOne(name:customListName),console.log(a)的输出吗? 当我使用 node shell 运行我的 app.js 时...浏览器给出一个错误...会话结束并崩溃......并且在 node shell 中它是相同的错误“项目”为 null 尝试使用postman发出API请求,并分享输出。 【参考方案1】:

仔细看你的list.ejs,里面有一个空格value="&lt;%= listTitle %&gt; "&gt;

尝试删除空格,使其变为value="&lt;%= listTitle %&gt;"

或删除 list.ejs 中的“”value=&lt;%= listTitle %&gt;

【讨论】:

【参考方案2】:

似乎您的 ejs 代码传递带有额外空间的值,而 mongoose findOne 函数无法比较,因此它将 null 值作为回调函数中的参数传递。 .因此,更改发布路线中的一行将解决问题。 const listName = req.body.list.slice(0,-1); //for removing an extra space。 希望这能解决您的问题。

【讨论】:

Anash Shelat:谢谢兄弟的帮助....祝您有美好的一天....上帝保佑.....谢谢:)【参考方案3】:

从该行中删除一个多余的空格。它会正常工作的。

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

【讨论】:

【参考方案4】:
app.post("/",async function(req, res)

  const itemName = req.body.newItem;
  const listName=req.body.list;
  const item= new Item(
    name:itemName
  );
  if(listName==="Today")
   await item.save();
    res.redirect("/");
  
  else
    const listOne = await List.findOne(name:`favico.ico`)//listName Is "Today" //there is no name=="Today" , hence null 
    console.log(listOne) //gives the result
 res.redirect("/"+listName); 
    
);

【讨论】:

以上是关于TypeError:无法使用nodejs在mongodb中读取null的属性“项目”的主要内容,如果未能解决你的问题,请参考以下文章

TypeError:无法在nodejs中读取未定义的属性“email”

TypeError:无法读取未定义的nodejs请求http的属性'0'

NodeJs,mongoDB:TypeError:无法读取未定义的属性“全名”

TypeError:无法读取未定义的属性“get”(nodejs)

Nodejs Promise TypeError:无法读取未定义的属性'then'

NodeJS Mongoose record.save TypeError