Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

toObject minimization not working with getters #1607

Closed
lbeschastny opened this issue Aug 1, 2013 · 4 comments · Fixed by #1744
Closed

toObject minimization not working with getters #1607

lbeschastny opened this issue Aug 1, 2013 · 4 comments · Fixed by #1744
Labels
enhancement This issue is a user-facing general improvement that doesn't fix a bug or add a new feature
Milestone

Comments

@lbeschastny
Copy link
Contributor

I played i bit with toObject method and found, that minimize: true flag is being ignored when getters: true is set:

{Schema} = mongoose = require 'mongoose'
ObjectId = Schema.ObjectId

Element = mongoose.model 'Element', new Schema
  field1: String
  field2: String
  nested: field: String

doc = new Element field1: 'foo'

console.log 'nice', doc.toObject minimize: yes
console.log 'ugly', doc.toObject minimize: yes, getters: yes
nice { field1: 'foo', _id: 51fa92d61061e9ce7e000001 }
ugly { field1: 'foo',
  _id: 51fa92d61061e9ce7e000001,
  id: '51fa92d61061e9ce7e000001',
  __v: undefined,
  nested: { field: undefined },
  field2: undefined }

It's not a problem for top-level fields, because JSON serialization removes such fields. But nested field becomes an empty object, which is not what I want to send to the client:

{ field1: 'foo',
  _id: '51fa9436bd6afbc707000001',
  id: '51fa9436bd6afbc707000001',
  nested: {} }

It's not only about the amount of data I'm sending. For most client side frameworks {} means that my document has a nested sub-document, which is not true.

@ebensing
Copy link
Contributor

ebensing commented Aug 1, 2013

Looking into this

@ebensing
Copy link
Contributor

ebensing commented Aug 2, 2013

This is something we'd like to support. Try and get it in a 3.7.x release

@JedWatson
Copy link
Contributor

I experimented with fixing this, added a test to test/document.test.js and modified the toObject method in lib/document.js

You can see the changes in my branch: https://github.com/JedWatson/mongoose/commits/master

Mainly adding the following to Document.prototype.toObject:

if (options.getters && options.minimize) {
  var minimize = function(obj) {
    var keys = Object.keys(obj)
      , i = keys.length
    while (i--) {
      if (!Array.isArray(obj[keys[i]]) && obj[keys[i]] === Object(obj[keys[i]])) {
        obj[keys[i]] = minimize(obj[keys[i]]);
      }
      if (obj[keys[i]] === undefined) {
        delete obj[keys[i]];
      }
    }
    return Object.keys(obj).length ? obj : undefined;
  }
  ret = minimize(ret) || {};
}

I'm not happy with the performance of this as a solution (it's a bit of a sledgehammer), but if somebody could confirm that this is the expected behaviour, I'll see if I can work out how to fix applyGetters and utils.clone to address the underlying issue.

@JedWatson
Copy link
Contributor

After cleaning up the code (so that I'm using an external function instead of creating it in toObject) this approach actually doesn't seem to have much of a negative performance impact, I'll create a pull request in case you're happy with it as a solution.

aheckmann added a commit that referenced this issue Oct 21, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement This issue is a user-facing general improvement that doesn't fix a bug or add a new feature
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants