Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Object.assign() creates wierd properties when assigns mongoose doc

MessageThread.findById(req.body._id)
      .populate({ path: "messages" })
      .exec((err, foundMessageThread) => {
        var filtered = foundMessageThread.messages.map(message=>{
          return Object.assign({}, message, {isRead: true});
        })
        console.log("filtered", filtered);

      });

console.log shows:

{ '$__':
 InternalCache {
   strictMode: true,
   selected: {},
   shardval: undefined,
   saveError: undefined,
   validationError: undefined,
   adhocPaths: undefined,
   removing: undefined,
   inserting: undefined,
   version: undefined,
   getters: {},
   _id: 5a4c7f2d8b49fc260c396f55,
   populate: undefined,
   populated: undefined,
   wasPopulated: true,
   scope: undefined,
   activePaths: [Object],
   pathsToScopes: {},
   ownerDocument: undefined,
   fullPath: undefined,
   emitter: [Object],
   '$options': true },
isNew: false,
errors: undefined,
_doc:
 { sentAt: 2018-01-03T06:58:53.188Z,
   isRead: false,
   _id: 5a4c7f2d8b49fc260c396f55,
   sender: 5a4b77767251b44cd870219f,
   reciever: 5a4b780a7251b44cd87021a1,
   text: 'qwe',
   __v: 0 },
'$init': true,
isRead: true },
......

it repeats many times. I suppose it (InternalCache { strictMode: true...) relates to message that is taken from foundMessageThread. And it reveals its metadata(in my term) while assigning. Because:

MessageThread.findById(req.body._id)
  .populate({ path: "messages" })
  .exec((err, foundMessageThread) => {
    var filtered = foundMessageThread.messages.map(message=>{
      console.log("message", message)
      return Object.assign({}, message, {isRead: true});
    })
    console.log("filtered", filtered);

  });

console.log shows

{ sentAt: 2018-01-03T06:58:53.188Z,
  isRead: false,
  _id: 5a4c7f2d8b49fc260c396f55,
  sender: 5a4b77767251b44cd870219f,
  reciever: 5a4b780a7251b44cd87021a1,
  text: 'qwe',
  __v: 0 },
....

My question:

  1. Is it normal behavior?
  2. If it is how to fix it? Because "metadata" prevents objects being assigned.

P.S. I've tried:

MessageThread.findById(req.body._id)
  .populate({ path: "messages" })
  .exec((err, foundMessageThread) => {
    var filtered = foundMessageThread.messages.map(message=>{
      return **Object.assign({}, message._doc, {isRead: true})**;
    })
    console.log("filtered", filtered);

  });
like image 964
m_rd_n Avatar asked Jan 03 '18 20:01

m_rd_n


People also ask

What is object assign ()?

The Object.assign() method copies all enumerable own properties from one or more source objects to a target object. It returns the modified target object.

What does ES6 object assign do?

assign() method in ES6. The Object. assign() copies all enumerable and own properties from the source objects to the target object. It returns the target object.

What is Mongoose API?

Mongoose is an Object Data Modeling (ODM) library for MongoDB and Node. js. It manages relationships between data, provides schema validation, and is used to translate between objects in code and the representation of those objects in MongoDB.


1 Answers

This is a normal behaviour with mongoose. Objects returned by mongoose wrap the actual data, so as to add behaviours (methods) to it.

You can get to the actual data object by using toObject method, for eg, message.toObject().

However there are properties like __v, which are used by mongoose for house keeping purposes. If you don't want them, you can modify the toObject method like this

messageSchema.set('toObject', {
  versionKey: false,
  transform: (doc, ret) => {
    delete ret.__v;
    return ret;
  },
});
like image 77
Akshendra Pratap Avatar answered Nov 03 '22 01:11

Akshendra Pratap