How do I include a virtual field in a JSON response
const ItemSchema = mongoose.Schema({
name: String,
time: { type: Date, default: Date.now }
});
ItemSchema.virtual('timeleft').get(function() {
this.timeleft = 24
var currentTime = moment();
var timeStored = moment.utc(this.time).local().format();
this.timeleft -= currentTime.diff(timeStored, 'h');
});
API call
app.get('/getAllItems', function(req, res, next) {
Item.find({}, function(err, items) {
res.json(items);
});
});
So technically the response won't include virtual timeleft field. Am I missing something?
[
{
name: "nike",
time: "21/2/22"
},
{
name: "adidas",
time: "21/2/22"
},
]
In Mongoose, a virtual is a property that is not stored in MongoDB. Virtuals are typically used for computed properties on documents. Your First Virtual.
Virtuals are document properties that do not persist or get stored in the MongoDB database, they only exist logically and are not written to the document's collection.
In MongoDB, all documents are unique because of the _id field or path that MongoDB uses to automatically create a new document. For this reason, finding a document is easy with Mongoose. To find a document using its _id field, we use the findById() function.
Mongoose is similar to an ORM (Object-Relational Mapper) you would use with a relational database. Both ODMs and ORMs can make your life easier with built-in structure and methods. The structure of an ODM or ORM will contain business logic that helps you organize data.
// use Schema like this
const ItemSchema = new Schema({
name: String,
time: { type: Date, default: Date.now }
}, {
toObject: { virtuals: true },
toJSON: { virtuals: true }
});
ItemSchema.virtual('timeleft').get(function() {
// this.timeleft = 24
var currentTime = moment();
var timeStored = moment.utc(this.time).local().format();
console.log(" ====== 000 ======== ", currentTime.diff(timeStored, 'h'))
return this.timeleft = currentTime.diff(timeStored, 'h');
});
const Item = mongoose.model('Item', ItemSchema);
new Item({
name: 'Axl'
}).save((err, result) => {
console.log("=== err ", err, "=== result ", result)
});
Item.find({}, function(err, items) {
console.log("=========", items)
});
According to Mongoose docs Mongoose virtuals are not stored in MongoDB, which means you can't query based on Mongoose virtuals.
// Will **not** find any results, because `domain` is not stored in
// MongoDB.
const doc = await User.findOne({ domain: 'gmail.com' });
doc; // undefined
If you want to query by a computed property, you should set the property using a custom setter or pre save middleware.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With