Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tag: 1.1.9
Fetching contributors…

Cannot retrieve contributors at this time

80 lines (54 sloc) 2.641 kb

Virtual attributes

Mongoose supports virtual attributes. Virtual attributes are attributes that are convenient to have around but that do not get persisted to mongodb.

An example is helpful.

Example

Take the following schema:

var PersonSchema = new Schema({
    name: {
        first: String
      , last: String
    }
});

var Person = mongoose.model('Person', PersonSchema);

var theSituation = new Person({name: { first: 'Michael', last: 'Sorrentino' }});

Suppose you want to write theSituation's full name. You could do so via: console.log( theSituation.name.first + ' ' + theSituation.name.last );

It is more convenient to define a virtual attribute, name.full, so you can instead write:

console.log( theSituation.name.full ); 

To do so, you can declare a virtual attribute on the Schema, Person:

PersonSchema.virtual('name.full')
  .get( function () {
    return this.name.first + this.name.last;
  });

So when you get name.full, via

theSituation.name.full;

the implementation ends up invoking the getter function

function () {
  return this.name.first + this.name.last;
}

and returning it.

It would also be nice to be able to set this.name.first and this.name.last by setting this.name.full. For example, it would be nice if we wanted to change theSituation's name.first and name.last to 'The' and 'Situation' respectively just by invoking:

theSituation.set('name.full', 'The Situation');

Mongoose allows you to do this, too, via virtual attribute setters. You can define a virtual attribute setter thusly:

PersonSchema.virtual('name.full')
  .get( function () {
    return this.name.first + this.name.last;
  })
  .set( function (setFullNameTo) {
    var split = setFullNameTo.split(' ')
      , firstName = split[0], lastName = split[1];
    this.set('name.first', firstName);
    this.set('name.last', lastName);
  });

Then, when you invoke:

theSituation.set('name.full', 'The Situation');

and you save the document, then name.first and name.last will be changed in monbodb, but the mongodb document will not have persisted a name.full key or value to the database:

theSituation.save( function (err) {
  Person.findById(theSituation._id, function (err, found) {
    console.log(found.name.first); // 'The'
    console.log(found.name.last);  // 'Situation'
  });
});

If you want attributes that you can get and set but that are not themselves persisted to mongodb, virtual attributes is the Mongoose feature for you.

Jump to Line
Something went wrong with that request. Please try again.