Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoose key/val set on instance not show in JSON or Console.. why?

I have some information on my mongoose models which is transient. For performance reasons I dont wish to store it against the model.. But I do want to be able to provide this information to clients that connect to my server and ask for it.

Here's a simple example:

 var mongoose = require('mongoose'),
     db = require('./dbconn').dbconn;

 var PersonSchema = new mongoose.Schema({
  name    : String,
  age     : Number,
});

var Person = db.model('Person', PersonSchema);
var fred = new Person({ name: 'fred', age: 100 });

The Person schema has two attributes that I want to store (name, and age).. This works.. and we see in the console:

console.log(fred);

{ name: 'fred', age: 100, _id: 509edc9d8aafee8672000001 }

I do however have one attribute ("status") that rapidly changes and I dont want to store this in the database.. but I do want to track it dynamically and provide it to clients so I add it onto the instance as a key/val pair.

fred.status = "alive";

If we look at fred in the console again after adding the "alive" key/val pair we again see fred, but his status isnt shown:

{ name: 'fred', age: 100, _id: 509edc9d8aafee8672000001 }

Yet the key/val pair is definitely there.. we see that:

console.log(fred.status);

renders:

alive

The same is true of the JSON representation of the object that I'm sending to clients.. the "status" isnt included..

I dont understand why.. can anyone help?

Or, alternatively, is there a better approach for adding attributes to mongoose schemas that aren't persisted to the database?

like image 567
Duncan_m Avatar asked Nov 10 '12 23:11

Duncan_m


2 Answers

Adding the following to your schema should do what you want:

PersonSchema.virtual('status').get(function() {
  return this._status;
});

PersonSchema.virtual('status').set(function(status) {
  return this._status = status;
});

PersonSchema.set('toObject', {
  getters: true
});

This adds the virtual attribute status - it will not be persisted because it's a virtual. The last part is needed to make your console log output correctly. From the docs:

To have all virtuals show up in your console.log output, set the toObject option to { getters: true }

Also note that you need to use an internal property name other than status (here I used _status). If you use the same name, you will enter an infinite recursive loop when executing a get.

like image 76
David Weldon Avatar answered Oct 04 '22 02:10

David Weldon


Simply call .toObject() on the data object.

For you code will be like:

fred.toObject()

like image 22
Amol M Kulkarni Avatar answered Oct 04 '22 02:10

Amol M Kulkarni