Can't get Mongoose virtuals to be part of the result object
Asked Answered
T

4

30

bI'm declaring a virtual that I want to appear as part of the results of its schema's queries, but it's not showing up when I do a console.log on the object. Here's the schema:

var schema = new mongoose.Schema(
{
    Name: { type: String }
},
{
    toObject: { virtuals: true }
});

schema.virtual("Greet").get(function()
{
    return "My name is " + this.Name;
});

Should that toObject not set the virtual as a property of the results of any queries? It does not, nor does schema.set("toObject", { virtuals: true }). Am I doing this right?

Tejeda answered 30/10, 2012 at 6:39 Comment(3)
I'm using version 3.3.1.Tejeda
myModel.find({}).exec(function(err, results) { console.log(JSON.stringify(results[0])); }Tejeda
@MikePateras - did you end up getting this working? If so, how? I'm having exactly the same issue.Afflatus
E
73

Because you're using JSON.stringify in your console.log call, that invokes the toJSON method on the model instance, not toObject.

So either omit the JSON.stringify in your call:

console.log(results[0]);

Or set the toJSON option on the schema like you're currently setting the toObject option.

{
    toObject: { virtuals: true },
    toJSON: { virtuals: true }
});
Edina answered 31/10, 2012 at 0:27 Comment(12)
I have had this same problem for at least 2 days - and no combination of toObject/toJSON with virtuals enabled has worked. I just can't get virtuals to output. Driving me absolutely batty!Afflatus
I ended up fixing it - I wasn't aware I needed both of these properties to be defined. Drove me nuts. lolAfflatus
Great question; great answer. This should be accepted as correct.Berthaberthe
Defining both properties for toObject and toJSON worked for meWolver
Where does the documentation state that you have to add toObject: { virtuals: true }, toJSON: { virtuals: true } ?Erastes
@ChrisRch that's the whole point there is nothing about itPivoting
That's one of the biggest downsides of Mongoose. Poor documentation and quirks. Currently working on a project using native MongoDB driver without Mongoose. A bit more cumbersome but gets the job done.Erastes
In Mongoose v4.0 I am able to get virtuals to work after a query with only toJSON: { virtuals: true }, no need for toObject: { virtuals: true }Stocktaking
This worked for me. UserSchema.set('toJSON', { getters: true, virtuals: true }); UserSchema.set('toObject', { getters: true, virtuals: true });Aldin
@ChrisRich: You can trace back to 2.7.X docs the virtuals option in toObject and toJSON. Here's the current one.Blissful
@Edina I dont understand why mongoose invokes toJSON automatically ?Unsex
@Unsex Mongoose doesn't invoke it, JSON.stringify() does. From the docs: "If the value has a toJSON() method, it's responsible to define what data will be serialized."Edina
T
3

My mistake was not including the needed fields in the query. If they are not selected in projection, then mongoose does not knows how to combine/calculate the virtual field.

Tumulus answered 19/6, 2019 at 12:24 Comment(1)
I had the problem with a redefined _id field (random string), and _id fields are always projected.Gath
A
1

I ended up here doing something really silly. I was using Doc.find instead of Doc.findOne and so I was trying to access the virtual on the document array instead of on the document itself.

Anderson answered 11/8, 2017 at 3:27 Comment(0)
F
0
userSchema.virtual('fullName').get(function () {
   return this.firstName + " " + this.lastName
});
const doc = await model.findOne(query);
return doc.toObject({ virtuals: true });
Flatt answered 21/1 at 6:21 Comment(1)
Thank you for your interest in contributing to the Stack Overflow community. This question already has a few answers—including one that has been extensively validated by the community. Are you certain your approach hasn’t been given previously? If so, it would be useful to explain how your approach is different, under what circumstances your approach might be preferred, and/or why you think the previous answers aren’t sufficient. Can you kindly edit your answer to offer an explanation?Ladybird

© 2022 - 2024 — McMap. All rights reserved.