2

I have an object which has fields that are sometimes empty on save. My initial thought was to remove empty fields on pre-save, but for some reason that doesn't seem to be working. The object values are still there after they are saved.

module.exports = function(req, res, next) {
var newRecipe = new Recipe(req.body);

newRecipe.pre('save', function (next) {

  var that = this.data;

  Object.keys(that.data).forEach(function(key) {
    if(that.data.hasOwnProperty(key)){
      if(typeof that.data[key] != 'undefined'){
        if (!that.data[key].length){
          delete that.data[key];
       };
    }
  }
});

  next(); 
});

newRecipe.save(function(err, recipe) {
  if (err) {
    console.log(err);
    res.sendStatus(500);
  } else {
    res.sendStatus(200);
  }
}); 
 };

Here is my incoming object:

  { 
  notes: [],
  isHostessGift: false,
  playbook: {},
  location: {},
  wine: { ingredient: false, pairing: false },
  coupons: [],
  ingredients: [{ item: 'd' }],
  categories: { dishType: ["Beverage"], mainIngredient: ["d"] },
  directions: [{ step: 'd' }],
  serves: 9,
  cookTime: 9,
  prepTime: 8,
  headline: 'ccc' 
}

Is there a better approach to this?

Edit: Working from chridam's answer for some reason inherited properties are passing through the hasOwn Property function.

 var hasOwnProperty = Object.prototype.hasOwnProperty;

function isPropertyEmpty(obj) {
if (obj == null)       return true;
if (obj.length > 0)    return false;
if (obj.length === 0)  return true;
for (var key in obj) {
    if (hasOwnProperty.call(obj, key)){
        console.log(key);
    } 
}
return true;


}



module.exports = function(req, res, next) {
    var newRecipe = new Recipe(req.body);

newRecipe.pre('save', function (next) {

 var doc = this;
  Object.keys(doc).forEach(function(key) {
      if (isPropertyEmpty(doc[key])){
          // console.log(_.omit(doc, doc[key]));
      };
  }); 

 console.log(doc); 


  next(); 
});

Consoling out the doc:

strictMode
selected
shardval
saveError
validationError
adhocPaths
removing
inserting
version
getters
_id
populate
populated
wasPopulated
scope
activePaths
ownerDocument
fullPath
emitter
createdAt
sites
published
featured
data
_id
slug
image
$__original_save
save
$__original_save
save
{ image: 'lol.jpg',
  slug: 'lol',
  _id: 561522878ff1d2f9ae9b4323,
  data: 
   { headline: 'lol',
     prepTime: 22,
     cookTime: 6,
     serves: 8,
     directions: [ [Object] ],
     categories: { mainIngredient: [Object], dishType: [Object] },
     ingredients: [ [Object] ],
     coupons: [],
     wine: { pairing: false, ingredient: false },
     location: {},
     playbook: {},
     isHostessGift: false,
     notes: [] },
  featured: false,
  published: false,
  sites: [ 'HOL' ],
  createdAt: Wed Oct 07 2015 09:47:51 GMT-0400 (EDT) }
2
  • Can you display your schema please ? Commented Oct 6, 2015 at 20:51
  • You can delete the properties form the data object, but the Schema is concrete. All properties that are undefined will be saved by mongoose with a default (empty, null, '') value. Commented Oct 7, 2015 at 1:53

1 Answer 1

2

I was having a lot of problems with this solution when there were nested schemas with optional Array fields. I solved this by creating a new type:

optional_array = 
  type: Mixed
  validate: 
    validator: (v) ->
      return v instanceof Array
    message: '{VALUE} needs to be an array.'

and then setting all my fields to optional_array instead of Array.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.