【问题标题】:How to populate in NodeJS and Mongoose a Post which need to be referred to a Username如何在 NodeJS 和 Mongoose 中填充需要引用用户名的帖子
【发布时间】:2020-05-08 13:56:30
【问题描述】:

我在我的 NodeJs API 和 Mongo 中遇到问题,我必须使用用户名字符串在字段用户名中发布和填充。

当我发布时,我收到此错误:

“TypeError: newPost.save(...).populate 不是函数”

后模型:

const mongoose = require("mongoose");

const schema = {
    text: {
        type: String,
        required: true,
        unique: true
    },

    username: {
        type: mongoose.Schema.Types.String,
        ref: "Profile",
        required: true
    },

    image: {
        type: String,
        default: "https://via.placeholder.com/150",
        required: false
    },
    createdAt: {
        type: Date,
        default: Date.now,
        required: false
    },

    updatedAt: {
        type: Date,
        default: Date.now,
        required: false
    }
};

const collectionName = "posts";
const postSchema = mongoose.Schema(schema);
const Post = mongoose.model(collectionName, postSchema);

module.exports = Post;

这是我在做 post 方法的地方:

postRouter.post("/", async (req, res) => {
    try {
        const newPost = await Posts.create(req.body);

        const username = await Profiles.findOne({
            username: req.body.username
        });

        if (!username) res.status(400).send("Username not found");

        newPost.save().populate(username.username);

        res.send({ success: "Post added", newPost });
    } catch (error) {
        res.status(500).send(error);
        console.log(error);
    }
});

响应输出应该如何:

{
        "_id": "5d93ac84b86e220017e76ae1", //server generated
        "text": "this is a text 12312 1 3 1",  <<--- THIS IS THE ONLY ONE SENDING"
        "username": "admin",<-- FROM REQ.body or params ??? 
        "createdAt": "2019-10-01T19:44:04.496Z", //server generated
        "updatedAt": "2019-10-01T19:44:04.496Z", //server generated
        "image": ... //server generated on upload, set a default here
    }

我也很高兴知道这样的路线的想法是否有意义,因为帖子需要有用户名,如果最好将它放在正文或请求的参数中。

【问题讨论】:

标签: node.js mongodb mongoose


【解决方案1】:

当我发布时,我收到此错误:“TypeError: newPost.save(...).populate is not a function”

您只需在save 返回类型上使用populate,即(来自API documentationPromise。需要在populate 调用之前等待承诺。

postRouter.post("/", async (req, res) => {
    try {
        const newPost = await Posts.create(req.body);

        const username = await Profiles.findOne({
            username: req.body.username
        });

        if (!username) res.status(400).send("Username not found");

        const addedPost = await newPost.save();  // <-- Here
        addedPost.populate(username.username);   // <-- Then populate here

        res.send({ success: "Post added", newPost });
    } catch (error) {
        res.status(500).send(error);
        console.log(error);
    }
});

我也很高兴知道这样的路线的想法是否有意义,因为帖子需要有用户名,如果最好将它放在正文或请求的参数中。

  • 您的路线似乎是 / 以创建新帖子。将其命名为/post 可能更清楚。

  • 如果您将用户名放入请求中,例如:/post/:username,则表明帖子需要用户名。但是您无法提供所需的其他信息。因此,如果您的应用程序增长并且您需要另一个需要参数,您必须对 API 路由进行重大更改。

【讨论】:

    【解决方案2】:

    您无需填充配置文件用户名,因为您已经在 req.body.username 中拥有该值。

    您的代码也存在一些问题:

    1-) 您已经使用Posts.create 创建了一个帖子,因此无需使用newPost.save()

    2-) 如果不需要删除newPost.save(),则需要添加等待。

    3-) 如果不需要删除newPost.save(),则保存后不能使用填充。

    4-) 您需要在 400 情况下返回响应,使用您的代码,代码将在 400 情况下执行。

    5-) 在 catch 块中,你永远看不到 console.log(error)

    6-) 您正在创建一个帖子,并且在您检查用户名是否存在于个人资料中之后。 先检查用户名是否存在是正确的,找到后才创建帖子。

    所以代码一定是这样的:

    postRouter.post("/", async (req, res) => {
      try {
        const { username } = req.body;
    
        const profile = await Profiles.findOne({ username });
    
        if (!profile) {
          return res.status(400).send("Username not found");
        }
    
        let newPost = await Posts.create(req.body);
        newPost.username = username;
    
        res.send({ success: "Post added", newPost });
      } catch (error) {
        console.log(error);
        res.status(500).send(error);
      }
    });
    

    【讨论】:

      【解决方案3】:

      试试下面的代码 考虑到 req.body.username 将是猫鼬对象 Id

      postRouter.post("/", async (req, res) => {
        try {
      
          const username = await Posts.findOne({
            username: req.body.username
          });
      
          if (!username) {
            res.status(400).send("Username not found");
          } else {
            const newPost = await Posts.create(req.body); //might need remove if double entry created
            const post = await Posts.populate(newPost, {
              path: 'username'
            })
            res.send({
              success: "Post added",
              newPost
            });
      
          }
        } catch (error) {
          res.status(500).send(error);
          console.log(error);
        }
      });
      

      【讨论】:

        猜你喜欢
        • 2019-01-08
        • 1970-01-01
        • 2017-12-23
        • 2021-03-31
        • 2013-07-08
        • 2022-06-14
        • 1970-01-01
        • 2020-08-22
        • 2017-07-06
        相关资源
        最近更新 更多