MongooseJs Virtual Properties with NodeJs, MongoDB

In the tutorial, we show how to use MongooseJs Virtual Properties with NodeJs, MongoDB.

Related Posts:
Crud RestAPIs with NodeJS/Express, MongoDB using Mongoose
NodeJs/Express MongoDB One-to-Many related documents
Mongoose Many-to-Many related models with NodeJS/Express, MongoDB

Mongoose Virtual Property

We define a customerSchema as below:


// define a customer-schema
var customerSchema = mongoose.Schema({
  firstname: String,
  lastname: String
});

// create a model
var Customer = mongoose.model('Customer', customerSchema);

// create a document 
var peter = new Customer({
  firstname: 'Peter',
  lastname: 'Thomas'
});

How to get a customer’s fullname?
-> With traditional way, we can do as below:


console.log(peter.firstname + ' ' + peter.lastname); 
// -> Peter Thomas

Problems?
-> The above way is too cumbersome. We can use a new approach with Mongoose Virtual property.

Mongoose Virtual Properties are document properties that we can get and set but Not persisted to MongoDB.
– To combining fields, we use getters
– To de-composing a single value into multiple values for storage, we use setters


customerSchema.virtual('fullname').
  get(function() { return this.firstname + ' ' + this.lastname; }).
  set(function(value) {
    this.firstname = value.substr(0, value.indexOf(' '));
    this.lastname = value.substr(value.indexOf(' ') + 1);
});

Now, see the executing of below code:


// Use virtual getter
console.log(peter.fullname) // Peter Thomas

// Use virtual setter
peter.fullname = "Peter Wilson"
console.log(peter.firstname) // Peter
console.log(peter.lastname)  // Wilson

Note: ‘fullname’ will not be persisted to MongoDB. So we can NOT use virtual properties for building queries and field selection.

For saving bandwidth, we can use Aliases type of Virtual properties. With Aliases, we can make a readable name from a short property name which stored in MongoDB:


var customerSchema = mongoose.Schema({
	fn: {
		type: String,
		alias: 'firstname'
	},
	ln: {
		type: String,
		alias: 'lastname'
	}
});

Now, see the results of below code:


console.log(peter.firstname) // Peter
console.log(peter.fn) // Peter

Practice

Create NodeJs project

Following the guide to create a NodeJS/Express project.

Install Express/Mongoose by commandline:


npm install express mongoose --save

-> ‘package.json’ :


...

  "dependencies": {
    "express": "^4.16.3",
    "mongoose": "^5.0.14"
  }

...

Customer Schema


const mongoose = require('mongoose'), Schema = mongoose.Schema;

var customerSchema = mongoose.Schema({
	fn: {
		type: String,
		alias: 'firstname'
	},
	ln: {
		type: String,
		alias: 'lastname'
	}
});

customerSchema.virtual('fullname').
  get(function() { return this.firstname + ' ' + this.lastname; }).
  set(function(value) {
    this.firstname = value.substr(0, value.indexOf(' '));
    this.lastname = value.substr(value.indexOf(' ') + 1);
});

module.exports = mongoose.model('Customer', customerSchema);

Config MongoDB


module.exports = {
    url: 'mongodb://localhost:27017/jsa-nodejs-db'
}

Implement Express Server


var express = require('express');
var app = express();

// Configuring the database
const dbConfig = require('./app/config/db.config.js');
const mongoose = require('mongoose');

mongoose.Promise = global.Promise;

// Connecting to the database
mongoose.connect(dbConfig.url)
.then(() => {
    console.log("########Successfully connected to MongoDB.########\n");    
}).catch(err => {
    console.log('Could not connect to MongoDB.');
    process.exit();
});

const Customer = require('./app/model/customer.model.js')

// Create a Server
var server = app.listen(8081, function () {

  var host = server.address().address
  var port = server.address().port

  console.log("App listening at http://%s:%s", host, port)
  
  // Add Subject to MongoDB
  var peter = new Customer({
	  firstname: 'Peter',
	  lastname: 'Thomas'
  });
  
  // Save to MongoDB
  peter.save(function (err){
	  if(err) return console.error(err.stack)
	  console.log('Peter is added!');
	  console.log('Peter: ' + peter);
	  console.log("Peter's FirstName: " + peter.fn);
	  console.log("Peter's LastName: " + peter.lastname);
	  console.log("Peter's FullName: " + peter.fullname);
	  
	  // Just for waiting time
	  console.log('\n---Modified FullName and Updated---')
      console.log('---Note: Sleep 10s to interact with MongoDB collection---\n')
  });
  
  setTimeout(function() {
	  // Modify fullname of Peter then Update to MongoDB
	  peter.fullname = 'Peter Wilson'
	  peter.save(function (err){
		 if(err) return console.error(err.stack)
		 console.log('Peter: ' + peter);
		 console.log("Peter's FirstName: " + peter.fn);
		 console.log("Peter's LastName: " + peter.lastname);
		 console.log("Peter's FullName: " + peter.fullname);
	  });
  }, 10000);
})

Sourcecode

NodeJs-Mongoose-Virtual-Property

Run NodeJs App by commandline: node server.js
-> Results:

mongoose-virtuals-properties-alias-app console logs

mongoose-virtuals-properties-alias-mongodb-records

One thought on “MongooseJs Virtual Properties with NodeJs, MongoDB”

  1. I was suggested this website by my cousin. I am not sure whether this post is written by him as no one else know such detailed about my difficulty.

    You are amazing! Thanks!

Leave a Reply

Your email address will not be published. Required fields are marked *