So I know how to get a single virtual attribute, as stated in the Mongoose docs:
PersonSchema
.virtual('name.full')
.get(function () {
return this.name.first + ' ' + this.name.last;
});
But what if my schema is:
var PersonSchema = new Schema({
name: {
first: String
, last: String
},
arrayAttr: [{
attr1: String,
attr2: String
}]
})
And I want to add a virtual attribute for each nested object in arrayAttr:
PersonSchema.virtual('arrayAttr.full').get(function(){
return attr1+'.'+attr2;
});
Lemme know if I missed something here.
Array reduce method is very powerful and it can be used to safely access nested objects.
Accessing nested json objects is just like accessing nested arrays. Nested objects are the objects that are inside an another object. In the following example 'vehicles' is a object which is inside a main object called 'person'. Using dot notation the nested objects' property(car) is accessed.
Sure, you can define an extra schema, but mongoose is already doing this for you.
It is stored at
PersonSchema.path('arrayAttr').schema
So you can set a virtual by adding it to this schema
PersonSchema.path('arrayAttr').schema.virtual('full').get(function() {
return this.attr1 + '.' + this.attr2
})
If you want a calculated value from all the array elements here's an example:
const schema = new Schema({
name: String,
points: [{
p: { type: Number, required: true },
reason: { type: String, required: true },
date: { type: Date, default: Date.now }
}]
});
schema.virtual('totalPoints').get(function () {
let total = 0;
this.points.forEach(function(e) {
total += e.p;
});
return total;
});
User.create({
name: 'a',
points: [{ p: 1, reason: 'good person' }]
})
User.findOne().then(function(u) {
console.log(u.toJSON({virtuals: true}));
});
Returns to:
{ _id: 596b727fd4249421ba4de474,
__v: 0,
points:
[ { p: 1,
reason: 'good person',
_id: 596b727fd4249421ba4de475,
date: 2017-07-16T14:04:47.634Z,
id: '596b727fd4249421ba4de475' } ],
totalPoints: 1,
id: '596b727fd4249421ba4de474' }
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