I am setting up a virtual property on my user model to calculate how many posts the user has but when I log the value in my mocha tests, it logs Promise {}.
I am not sure why I am getting this because in my userSchema.virtual route it will log the post count properly as "POST COUNT: 1"
I think I am returning the value wrong or something? How do I return the value so it can be read??
Thank you!
Schema Virtual Property
userSchema.virtual("postCount").get(async function () {
const Post = mongoose.model("Post")
const posts = await Post.find({ userId: this._id })
console.log(`POST COUNT: `, posts.length). // correctly logs "POST COUNT: 1"
return posts.length
})
Test Code
const Assert = require("assert")
const User = require("../src/models/user-model")
const Post = require("../src/models/post-model")
describe("finding user will auto populate postCount", () => {
beforeEach(async () => {
const sarah = new User({
username: "sarahsmith",
email: "test@sarah.com",
password: "sarahsarah",
})
await sarah.save()
const post1 = new Post({
caption: "test post 1",
userId: sarah._id,
mediaUrl: "amazon/s3.com/1",
})
await post1.save()
})
it("calculates user's post count ", async () => {
const sarah = await User.findOne({ username: "sarahsmith" }) // WORKS
console.log(`SARAH POST COUNT`, sarah.postCount) // logs "Promise {<pending>} ??"
})
})
Turns out I needed to await when reading the property like this:
console.log(`SARAH POST COUNT`, await sarah.postCount)
...since the virtual("postCount") is an async function itself
I believe the issue is that you need to populate the virtual fields manually, as they will not be populated by default (see: https://mongoosejs.com/docs/populate.html#populate-virtuals).
This should work:
const sarah = await User.findOne({ username: "sarahsmith" }).populate('postCount');