Reputation: 407
I'm quite new to Node.js development. Also callbacks still quite bedazzle me although I have some experience with async functions.
I'm using mongoose's .find() function to search in a Users collection in the DB. The problem is I also want to display these users but I wouldn't want to display all the properties availible in the Database.
...
function(req,res){
User.find(function(err,users){
res.json(users);
})
}
...
This is how I'm currently getting all my users in the DB, but this also return passwords and other sensitive information. I would like to know the most effiecient way to "convert" this data into the same object without some properties or with altered properties like adding a "fullName" comprised of firstName + lastName;
So when returning all the users I would like to have something like
...
function(req,res){
User.find(function(err,users){
res.json(users.convertToOtherModel());
})
}
...
Not sure the "convertToOtherModel" function can be placed somewhere so that it works on users... but any idea on how to do this would help!
Upvotes: 1
Views: 1760
Reputation: 854
Override toJSON
method of your User schema.
UserSchema.methods.toJSON = function () {
var user = this;
// Modify your document object here
return { fullName: user.firstName + " " + user.lastName }
// Pick other fields too if you want
// _.pick(user, ["otherField"]);
};
Then send them like so -
User.find(function(err,users){
res.json(users);
})
Upvotes: 1
Reputation: 1495
personSchema
.virtual('fullName')
.get(function () {
return this.name.first + ' ' + this.name.last;
})
.set(function (v) {
this.name.first = v.substr(0, v.indexOf(' '));
this.name.last = v.substr(v.indexOf(' ') + 1);
})
For something like FullName
you can create virtual
schemas.
Link here: http://mongoosejs.com/docs/guide.html
You will have to choose what columns you want to output, i am not sure if you can specifically blacklist a column(All columns minus password column)
Upvotes: 2
Reputation: 122077
Instead of making query to return all fields you can pass second argument to find()
and specify which fields you want or don't want to return
User.find({}, {password: 0}, function(error, users) {
console.log(users)
})
You can also use aggregation framework
and create new field by concating values of different fields
User.aggregate([
{$project: {
username: '$username',
fullName: {$concat: ['$firstName', ' ', '$lastName']}
}}
], function(error, users) {
console.log(users)
})
Upvotes: 1
Reputation: 111414
You can do something like this to return only some of the properties:
function filterUser(user) {
let { property1, property2 } = user;
return { property1, property2 };
}
res.json( users.map(filterUser) );
Or a more portable way using lodash:
res.json( users.map(user => _.pick(user, ['prop1', 'prop2']));
See: https://lodash.com/docs/4.17.4#pick
To use the lodash version you first need to add:
const _ = require('lodash');
to your code, and run this in your project's directory:
npm install lodash --save
Upvotes: 2