Underscore.js.keys and .omit not working as expected

I am running MongoDB with Mongoose access to store custom records. I also have an underline on the server. I have a RESTful API with a route that returns a collection (array of objects) from a database. I want to return the complete collection to the client , but remove the password element from each object so that it doesn't get sent to the client. Before anyone says anything, I will use bcrypt for the salt and hash the password in the final version :)

Today I have only one record in the database, for the user "admin". Here is my route code:

app.get('/users', function(req, res) {
  User.find().sort({'userName': 'ascending'}).exec(function(err, data) {
    _.each(data, function (element, index, list) {
      console.log('userName=' + element.userName);
      console.log('password=' + element.password);
      delete element.password;
      console.log('keys: ' + _.keys(element));
      console.log('password=' + element.password);
      console.log(_.omit(element, 'password'));
    });
    res.json(data);
  });
});

      

What I get is sent back to the browser:

[{"_id":"54058e6eb53dd60730295f59","modifiedOn":"2014-09-01T15:19:10.012Z",
"userName":"administrator","password":"stackoverflow","role":"administrator",
"__v":0,"createdBy":"54058e6eb53dd60730295f59","createdOn":"2014-09-01T15:19:10.004Z",
"previousLogins":[],"accountIsLocked":false,"loginAttempts":0}]

      

What makes us different, since the operator res.json(data)

just sends the raw data

back to the browser, is not a problem. The problem is that delete

(and also if I use .omit

) doesn't seem to work in my collection! As you can see, there is a lot to debug console.log

, here's what happens:

userName=administrator
password=stackoverflow
keys: $__,isNew,errors,_maxListeners,_doc,_pres,_posts,save,_events
password=stackoverflow
{ _id: 54058e6eb53dd60730295f59,
  modifiedOn: Mon Sep 01 2014 19:19:10 GMT+0400 (GST),
  userName: 'administrator',
  password: 'stackoverflow',
  role: 'administrator',
  __v: 0,
  createdBy: 54058e6eb53dd60730295f59,
  createdOn: Mon Sep 01 2014 19:19:10 GMT+0400 (GST),
  previousLogins: [],
  accountIsLocked: false,
  loginAttempts: 0 }

      

The output _.keys

shows the keys (I'm guessing from the object prototype?) That I can't see when I do console.log(element)

, but none of the keys that are available through element.key

.

Any idea why I am seeing this behavior?

+3


source to share


1 answer


The problem is what data

gets passed into exec

the callback function - actually an object Document

that can be thought of as a collection Models

created by Mongoose. These objects have many useful methods, they remember the connection to the db, etc. - but you won't be able to treat them as simple objects.

The solution is to tell Mongoose that you really want plain JS objects to be the result of a query with lean()

:

User.find().sort({'userName': 'ascending'}).lean().exec(function(err, data) {
  // process the data
});

      



Also, you should be able to turn each model into a simple object using a method .toObject()

, and then filter it:

var filtered = _.map(data, function(model) {
  return _.omit(model.toObject(), 'password');
});
res.json(filtered);

      

... but I would rather use the first approach. )

+10


source







All Articles