mongoose
mongoose copied to clipboard
virtual path on array
in mongose guild doc there is a cool example. define .full virtual on sub documents name: {first:String, last:String}. then get virtual value by name.full.
but if i define virtual on array like this:
var schema = new Schema({
nums: [Number]
});
schema.virtual('nums.odd').get(...).
i cannot get it by dot path nums.odd. only write like this model.get('nums.odd').
is there a way to fix this? i'm running [email protected]
That's weird, that should work in theory. I'll investigate.
maybe my fault. only object path can define virtual append with dot. i don't know how mongoose do that. define a real property on that object? or intercept invoke on schema level?
here is some test code:
describe('gh-2306', function () {
it('allow define virtual on non-object path', function () {
var db = start();
var schema = new mongoose.Schema({ num: Number, str: String, nums: [Number] });
schema.virtual('num.power').get(function () {
return this.num * this.num;
});
schema.virtual('str.upper').get(function () {
return this.str.toUpperCase();
});
schema.virtual('nums.last').get(function () {
return this.nums[this.nums.length - 1];
});
var M = db.model('gh2306', schema);
var m = new M({ num: 2, str: 'a', nums: [1,2,3] });
assert.equal(m.num.power, 4);
assert.equal(m.str.upper, 'A');
assert.equal(m.nums.last, 3);
});
});
There is no good way to support this right now because getters and setters do not go through the . operator and virtuals are defined in the document level.
You can access the virtuals in the test above as m.get('num.power').
+1
We can't support schema.virtual('str.upper') because you can't define getters on primitive values in JavaScript, but schema.virtual('nums.last') and schema.virtual('nums.odd') are possible. We put in PR #14955 to add that feature.