Retrieving the ObjectID after a create or save of a Mongoose Model instance
I would just like to take a moment and celebrate writing my first POST api endpoint that creates a Mongoose object and saves it to the Mongodb. I held off celebrating after I wrote a GET, but now it's proper time. The hardest part about writing the POST was figuring out why I kept being unable to retrieve the new object's id. Searching surfaced what seemed to be simply accessing the "._id" or ".id" attribute of the new object instance. However, I kept getting errors of the form:
return this._id.toString(); ^ TypeError: Cannot call method 'toString' of undefined at model. (node_modules/mongoose/lib/mongoose/schema.js:45:23) at VirtualType.applyGetters (node_modules/mongoose/lib/mongoose/virtualtype.js:52:25) at model.Document.get (node_modules/mongoose/lib/mongoose/document.js:376:18) at model.Object.defineProperty.get [as id] (node_modules/mongoose/lib/mongoose/document.js:609:41) at Promise. (server.js:127:35) at Promise. (node_modules/mongoose/lib/mongoose/promise.js:120:8) at Promise.EventEmitter.emit (events.js:95:17) at Promise.emit (node_modules/mongoose/lib/mongoose/promise.js:57:38) at Promise.complete (node_modules/mongoose/lib/mongoose/promise.js:68:20) at complete (node_modules/mongoose/lib/mongoose/model.js:73:13)
or simply an "undefined" value when logging the .id or ._id property. It turns out the model was defined incorrectly because the '_id' property was specified as a string, like this:
contestData = { _id: String, words: [String], time_limit: Number, genre: [String], status: String, entries: [postData] };
Once the _id property was removed from the model definition, the _id property was accessible as expected.
contestData = { words: [String], time_limit: Number, genre: [String], status: String, entries: [postData] }; var contestSchema = new mongoose.Schema(contestData); var Contest = mongoose.model('Contest', contestSchema); app.post('/api/contests/new', function(request, response) { var c = new Contest(); c.words = request.body.words; c.time_limit = request.body.time_limit; c.genre = request.body.genre; c.status = "new"; c.entries = []; c.save(function (err) { if (err) return handleError(err); }); console.log('Saved: %s', c._id); response.redirect('/api/contests/' + c._id);