Virtuals are additional fields for a given model. Their values can be set manually or automatically with defined functionality. A common virtual property is the full name of a person, composed of user’s first and last name.
Keep in mind: virtual properties don’t get persisted in the database. They only exist logically and are not written to the document’s table.
Thinky Series Overview
Thinky Model
We’ll use the user schema below for further examples. The user schema consists of two non-virtual properties: first
and last
and the virtual fullname
property.
// define user schema
var User = thinky.createModel('user', {
first: String,
last: String,
fullname: {
_type: 'virtual',
default: function() {
return this.first + " " + this.last;
}
}
});
// create a document
var mentalist = new User({
first: 'Patrick',
last: 'Jane'
});
Assume we want to get the full name of mentalist
, we can do this manually appending the first
to last
property:
console.log(mentalist.first + ' ' + mentalist.last); // Patrick Jane
Additionally, we can directly use the fullname
property. The defined default function already concatenates the first
and last
values. The provided default function for the virtual property is automatically executed during object creation. Therefore, fullname
will return the desired value.
console.log(mentalist.fullname); // Patrick Jane
Define a Virtual Property
The code snippet above illustrates how to define the virtual property and a default function returning the virtual’s value. However, we can define separate functions to get
and set
the virtual property value.
The required model attribute: { _type: "virtual }"
. This tells Thinky to handle fullname
as virtual property.
var User = thinky.createModel('user', {
first: String,
last: String,
fullname: {
_type: "virtual",
}
});
Get Method
Actually, Thinky doesn’t split the getter and setter handling from normal model extension. We can use the known patterns and define additional model functions.
The virtuals get
method is a function returning a the virtual value. You can do complex processing or just concatenate single document field values.
User.define('getFullname', function() {
return this.first + ' ' + this.last;
});
The code example above just concatenates the first
and last
property values.
console.log(mentalist.fullname); // Patrick Jane
Set Method
Defining set
ter methods follows the same approach as get
ters: define a model function.
User.define('setFullname', function(name) {
var split = name.split(' ');
this.fullname = name;
this.first = split[0];
this.last = split[1];
});
The first part of name
is assigned to the first
and the second part to the last
property. This set
method will override the previous model values and assign the ones we pass as name
property.
var humor = new User({});
humor.setFullname('Kimball Cho');
console.log(humor.first); // Kimball
console.log(humor.last); // Cho
humor.getFullname(); // Kimball Cho
Regenerate Virtual Field Values
Thinky doesn’t recognize manually changed model values for virtual properties. The virtual field will still have the old value after changing any affected static property. You've to call generateVirtualValues()
to regenerate them.
humor.getFullname(); // Kimball Cho
humor.first = 'Wayne';
humor.last = 'Rigsby';
humor.getFullname(); // Kimball Cho
humor.generateVirtualValues();
humor.getFullname(); // Wayne Rigsby
Saving a document will do the job for you, automatically.
humor.getFullname(); // Kimball Cho
humor.first = 'Wayne';
humor.last = 'Rigsby';
humor.save().then(function() {
humor.getFullname(); // Wayne Rigsby
}).error(function(err) {
console.log(err);
});
Queries and Field Selection
Virtuals are NOT available for document queries or field selection. Only non-virtual properties work for queries and field selections.
Conclusion
As you see, virtual properties aren’t static model properties. They’re additional model functions returning values based on the default schema fields.
Additional Resources
- Related blog post: Virtuals in Mongoose
- Wondering about the variable names? We used actors from The Mentalist TV show