TypeError:无法使用nodejs在monogdb中读取null的属性“ items”

时间:2020-05-25 10:40:33

标签: mongodb mongoose ejs

我正在创建一个待办事项列表应用程序,该应用程序动态添加项目并通过url动态创建列表。例如:http://localhost:3000/Home将创建一个“主页”列表,而http://localhost:3000/Work将创建“工作”并添加一些默认值。但是,当我通过类似http://localhost:3000/Home的url并添加新项时,则会引发错误。

以下是我的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") -%>

有什么解决方法吗?

4 个答案:

答案 0 :(得分:1)

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); 
    }
});

答案 1 :(得分:1)

从此行删除多余的空间。它将正常工作。

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

答案 2 :(得分:1)

好像您的ejs代码传递带有额外空间的值,而mongoose findOne函数无法比较,因此它在回调函数中将null值作为参数传递。 。因此,在您的张贴路线中更改一行将解决此问题。 'DIRS': [os.path.join(BASE_DIR, 'templates')]。 希望这能解决您的问题。

答案 3 :(得分:0)

仔细看你的list.ejs,里面有空格
value="<%= listTitle %> ">

尝试删除空间,使其成为
value="<%= listTitle %>"

或删除 list.ejs 中的“”
value=<%= listTitle %>