15

I want to add to the return data from a mongoose query:

User.findById(userId, function(err, data) {
  if (!err) {
    data.newvar = 'Hello, world';
  }
});

However, when I console log the output, the newvar does not exist. I've also tried this using Underscore's extend:

_.extend(data, {'newvar': 'Hello, world'});

With no luck either. Since I have nested documents, using a shallow copy won't work. Is there any way to append data here?

James
  • 6,471
  • 11
  • 59
  • 86

3 Answers3

23

One way to handle this is to convert your mongoose model instance into a plain object that you have full control over by calling toObject() on it:

User.findById(userId, function(err, data) {
  if (!err) {
    data = data.toObject();
    data.newvar = 'Hello, world';
  }
});

If you want a more structured solution, you can add virtual attributes to your schema as described here.

Community
  • 1
  • 1
JohnnyHK
  • 305,182
  • 66
  • 621
  • 471
  • Thanks for this. I was passing user records from mongoose straight into JWT and the 'expiration' field wasn't getting applied for this reason. No warning or anything. – backdesk Feb 09 '15 at 14:09
5

As it turns out, Mongoose documents are their own special class and not standard Javascript objects. In order to get a javascript option that can be extended, you must use the toObject() method.

James
  • 6,471
  • 11
  • 59
  • 86
2

Now you can use lean() method to return a plain js object:

User.findById(userId)
  .lean()
  .exec( function(err, data) {
    if (!err) {
      data.newvar = 'Hello, world';
    }
  });

Why can't you modify the data returned by a Mongoose Query (ex: findById)

Community
  • 1
  • 1
Sten Ka Razin
  • 883
  • 1
  • 10
  • 23