Skip to content

Commit

Permalink
Set properties plugin for mongoose
Browse files Browse the repository at this point in the history
  • Loading branch information
Adam Buczynski committed Jun 11, 2016
1 parent 178ac31 commit 1d24ced
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 2 deletions.
99 changes: 99 additions & 0 deletions app/plugins/mongoose/set-properties.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/* jshint -W083 */
'use strict';

/**
* Dependencies
*/
let onlyId = require('../../helpers/only-id');

/**
* Recursive handler of objects
*/
function setObject(obj, data, parentPath) {

//Loop all the keys
for (let key in data) {
if (data.hasOwnProperty(key)) {

//Determine path
let path = parentPath ? (parentPath + '.' + key) : key;

//If the current value is undefined, we set the data to whatever is given
if (typeof obj[key] === 'undefined') {
obj[key] = data[key];
}

//If the value is an array, it requires further handling
else if (Array.isArray(obj[key])) {

//First, we would expect the data to be an array as well
if (!Array.isArray(data[key])) {
throw new Error(
'Path `' + path + '` in data is expected to be an array`'
);
}

//Simplify the objects
let current = onlyId(obj[key]);
let updated = onlyId(data[key]);

//Find items not present in the current array
if (updated.some(x => current.indexOf(x) === -1)) {
obj[key] = data[key];
}

//Find items not present in the updated array
else if (current.some(x => updated.indexOf(x) === -1)) {
obj[key] = data[key];
}
}

//If it's a date, check if the same
else if (obj[key] instanceof Date && data[key] instanceof Date) {
if (obj[key].getTime() !== data[key].getTime()) {
obj[key] = data[key];
}
}

//If the value is an object, it requires further handling
else if (typeof obj[key] === 'object') {

//First, we would expect the data to be an object as well
if (typeof data[key] !== 'object') {
throw new Error(
'Path `' + path + '` in data is expected to be an object`'
);
}

//If either the current value or the new value are null, it's safe
//to simply set the replacement value.
if (obj[key] === null || data[key] === null) {
obj[key] = data[key];
continue;
}

//Recursive object check
setObject(obj[key], data[key], key);
}

//Anything else, check if changed
else if (obj[key] !== data[key]) {
obj[key] = data[key];
}
}
}
}

/**
* Set properties helper which will set only properties that have changed
* Note that for arrays, it assume primitive values
*/
module.exports = function setProperties(schema) {

/**
* Method for all schema's
*/
schema.methods.setProperties = function(data) {
setObject(this, data);
};
};
1 change: 1 addition & 0 deletions app/services/db.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ let config = require('../config');
*/
mongoose.Promise = require('bluebird');
mongoose.plugin(require('../plugins/mongoose/to-json-plugin'));
mongoose.plugin(require('../plugins/mongoose/set-properties'));

/**
* Settings
Expand Down
8 changes: 6 additions & 2 deletions app/user/user.ctrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,12 @@ module.exports = {
*/
update(req, res, next) {

//Get user data and check if email changed
let user = Object.assign(req.user, req.data);
//Get user and data
let user = req.me;
let data = User.parseData(req.data);

//Set data and check if email changed
user.setProperties(data);
let isEmailChanged = user.isModified('email');

//Save user
Expand Down

0 comments on commit 1d24ced

Please sign in to comment.