My code is like this:
const mongoose = require('../common/mongoose.service').mongoose;
//..
//.. schema definition here..
//..
//-- create the model
const Student = mongoose.model('Student', studentSchema);
//-- delete "__v" field
studentSchema.set('toJSON', {
getters: true,
transform: (doc, ret) => {
delete ret.__v;
return ret;
},
});
exports.createStudent = (studentData) => {
const student = new Student(studentData);
return student.save();
};
And it was giving me the _id
when I call this createStudent()
method from my Student
controller.
Now I was trying to get the inserted document, updated my code like this:
exports.createStudent = (studentData) => {
const student = new Student(studentData);
return student.save().then( s => { return s } ).catch( err => console.log(err) );
};
Package versions:
"mongoose": "^5.9.23",
"mongoose-sequence": "^5.2.2",
My questions:
createStudent
asynchronous. Is it needed?then()
of save()
methodYou need a little bit of refactoring here. Either you directly return the promise from the method or execute it and resolve the value as promise value.
exports.createStudent = (studentData) => {
const student = new Student(studentData);
return student.save().then( s => { return s } ).catch( err => console.log(err) );
};
In the above code, you have a return statement as well as then/catch, it turns out that while it is saving the user with User.save() which is asynchronous, your return doing an explicit return and in this case it would `undefined.
As mongoose returns promise for the save method,either you just call it like this
// return a promise here
exports.createStudent = (studentData) => {
const student = new Student(studentData);
return student.save()
};
Wherever you call the createStudent()
meaning a controller/service, just use then
and catch
or use async/await
. Let assume we're calling it in the following function.
function execute() {
createStudent({fname:'john', lname: 'doe'}).then(res => {
console.log("student: ", student);
}).catch(err => {
console.log(err);
//handle error
})
}
Or simply use async await to make it even more simpler
async function execute() {
try {
let student = await createStudent({fname:'john', lname: 'doe'});
console.log("student: ", student);
} catch(err) {
// handle error
}
}
To answer your second question, I am not sure whether we can use userSchema.set
to override the toJSON
, But I tried the following and it seems to be working as expected for me.
Here is a User
model. Do note that the toJSON
is inside the model property and I am deleting __v
and _id
properties here.
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var userSchema = new Schema({
name: {
type: String,
required: true,
maxlength: 30,
trim: true
},
role: {
type: Number,
default: 0
},
todos: [{
type: Schema.Types.ObjectId,
ref: "Todo"
}]
}, {
toJSON: {
getters: true,
transform: function(doc, ret) {
delete ret._id;
delete ret.__v
}
}
});
module.exports = mongoose.model("User", userSchema)
I have a user/
which simply fetches all the user from my DB and it returns exactly the kind of response I am looking for, no __v
and _id
properties in it.