Mongoose Schema中声明的hello方法无法调用的问题
解决mongoose实例方法调用报错:TypeError: user.hello is not a function
嘿,我一眼就看出问题啦!你遇到的这个错误,根源在于User.find()返回的结果类型不对——它返回的是一个包含匹配文档的数组,而你定义的hello是Schema的实例方法,只能被单个User文档实例调用,数组自然没有这个方法呀!
下面给你两个针对性的修复方案,还有一个容易忽略的小细节要注意:
方案一:改用findOne()获取单个文档实例
因为你的username字段设置了unique: true,所以每个用户名只会对应一个用户,用findOne()直接获取单个匹配的文档实例就可以了。同时建议你统一用async/await搭配try/catch处理异步逻辑,不要混用回调和async/await,代码更清晰:
router.route("/login").post(async (req, res) => { try { // 用findOne代替find,获取单个文档实例 const user = await User.findOne({ username: req.body.username }); if (!user) { return res.status(404).json({ message: "用户不存在" }); } // 现在可以正常调用实例方法啦 user.hello(); res.end(); } catch (err) { console.error(err); res.status(500).json({ message: "服务器错误" }); } });
方案二:如果必须用find(),遍历数组调用方法
虽然你的场景下不太需要,但如果以后遇到需要匹配多个文档的情况,就得遍历数组里的每个文档实例再调用方法:
router.route("/login").post(async (req, res) => { try { const users = await User.find({ username: req.body.username }); if (users.length === 0) { return res.status(404).json({ message: "用户不存在" }); } // 遍历数组,每个文档实例单独调用hello方法 users.forEach(user => user.hello()); res.end(); } catch (err) { console.error(err); res.status(500).json({ message: "服务器错误" }); } });
额外注意:实例方法不要用箭头函数
你定义hello方法的时候用了箭头函数,这其实是个隐患!箭头函数会绑定外部作用域的this,而mongoose实例方法里需要的是当前文档实例的this(比如以后要访问this.username时),所以一定要改成普通函数:
// 把箭头函数改成普通函数 UserSchema.methods.hello = function() { console.log("hello from method"); // 以后如果要访问文档属性,比如this.username,这样才能正确获取 };
内容的提问来源于stack exchange,提问作者Syntax Hacker
相关产品推荐
相关产品推荐

