Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding a MongoDB document by ObjectId with Mongoose

I am trying to update a document in MongoDB by finding it by the ObjectId. The work flow is as follows (this is for a blog).

  1. Create a new post in MongoDB by passing a title and body. The ObjectId is automatically created.
  2. Go to edit the post. It uses the ObjectId from the URL to grab it from the database and display it in the same new post form, just with the preexisting values.
  3. When the submit button is clicked I want to find the document by the ObjectId and update the values in the database with those in the post form.

Step 1 & 2 work fine, but step 3 doesn't seem to be working. It redirects to the page I need it to. But the database has not been updated. It's the same value as it was before.

Here's the relevant code for the update post portion:

app.js

app.post "/office/post/:id/update", ensureAuthenticated, routes.updatePost

routes/index.js

mongoose = require 'mongoose'
ObjectId = mongoose.Types.ObjectId

Post = require '../models/Post'

...

updatePost: function(req, res) {
  var o_id, the_id;

  the_id = req.params.id;
  console.log(the_id); // 510e05114e2fd6ce61000001

  o_id = ObjectId.fromString(the_id);
  console.log(o_id); // 510e05114e2fd6ce61000001

  return Post.update({
    "_id": ObjectId.fromString(the_id)
  }, {
    "title": "CHANGE"
  }, res.redirect("/office/edit/posts"));
}

I'm using Express and Mongoose.

This is also the post model if that helps:

(function() {
  var Post, Schema, mongoose;

  mongoose = require('mongoose');

  Schema = mongoose.Schema;

  Post = new Schema({
    title: String,
    subhead: String,
    body: String,
    publish_date: {
      type: Date,
      "default": Date.now
    },
    mod_date: {
      type: Date,
      "default": Date.now
    }
  });

  module.exports = mongoose.model('Post', Post);

}).call(this);

And here's the code for the edit blog post view:

app.js

app.get("/office/post/:id/edit", ensureAuthenticated, routes.editPost);

routes/index.js

editPost: function(req, res) {
  return Post.findById(req.params.id, function(err, post) {
    return res.render('edit-post', {
      post: post,
      title: post.title
    });
  });
}
like image 713
David Yeiser Avatar asked Feb 20 '13 23:02

David Yeiser


People also ask

What is ObjectId in Mongoose?

An ObjectID is a 12-byte Field Of BSON type. The first 4 bytes representing the Unix Timestamp of the document. The next 3 bytes are the machine Id on which the MongoDB server is running.

What does find by ID return Mongoose?

findById returns the document where the _id field matches the specified id . If the document is not found, the function returns null .

What is the use of ObjectId in MongoDB?

MongoDB uses ObjectIds as the default value of _id field of each document, which is generated during the creation of any document. Object ID is treated as the primary key within any MongoDB collection. It is a unique identifier for each document or record. Syntax: ObjectId(<hexadecimal>).

Where is MongoDB record by ID?

MongoDB provides a function with the name findById() which is used to retrieve the document matching the 'id' as specified by the user. In order to use findById in MongoDB, find() function is used. If no document is found matching the specified 'id', it returns null.


1 Answers

The problem is how you call update

return Post.update({
    "_id": ObjectId.fromString(the_id)
}, {
    "title": "CHANGE"
}, res.redirect("/office/edit/posts"));

The last argument will actually redirect the page, whereas update expects a function to be called when the update is complete

You should pass in

return Post.update({
    "_id": ObjectId.fromString(the_id)
}, {
    "title": "CHANGE"
}, function(err, model) {
    if (err) // handleerr

    res.redirect("/office/edit/posts"));
});

That way, we only redirect once the model is successfully updated

like image 163
Benoir Avatar answered Sep 28 '22 03:09

Benoir