0

My studentApi.js is as follows, router.param() is used to save code for repeating again and againt.

router.param('post', function (req, res, next, id) {
    var query = Post.findById(id);
    query.exec(function (err, post) {
        if (err) { return next(err); }
        if (!post) { return next(new Error('Can\'t find post')); }
        req.post = post;
        return next();
    })
});
router.put('/posts/:post/upvote', function (req, res, next) {
    res.post.upvote(function (err, post) {
        if (err) { return next(err);}
    });
});

In angular I am calling like

 o.upvote = function (post) {
        return $http.put('/studentapi/posts/' + post._id + '/upvote')
          .success(function (data) {
              alert("post voted");
              post.upvotes += 1;
          });
    };

Error: enter image description here

My model is as follows, calling upvote method internally from model.

var mongoose = require('mongoose');
var PostSchema = new mongoose.Schema({
    title: String,
    link: String,
    upvotes: { type: Number, default: 0 },
    downvotes: { type: Number, default: 0 },
    comments: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Comment' }]
});

mongoose.model('Post', PostSchema);

PostSchema.methods.upvote = function (cb) {
    this.upvotes += 1;
    this.save(cb);
}

enter image description here

17
  • is your api up and running? And in your studentApi.js there is only 'post/:post' where is the code initializing it with "/studentapi" ? Could be possible that you're missing some initialization. Try out PUT on "/posts/" without "studentapi" . Or you have "/studentApi" and not "studentapi" Commented Oct 11, 2015 at 10:14
  • Yup, api is up and running, already working with simple get request. I get the record from db and bind successfully. In this case I'm updating record I pass the parameter as above but 404. Commented Oct 11, 2015 at 10:17
  • studentApi.js seem to be executed server-side with node, so alert() should not exist except if you import a function with the same name. Then, what is res.post, is it a mongodb linked model? And finally what have you in the node console? Commented Oct 11, 2015 at 10:18
  • 1
    Well, you're providing your "get" route where is the .put route ? I mean you can't do an HTTP PUT if you just have a "GET" defined for that URL. Commented Oct 11, 2015 at 10:18
  • 1
    Store something in req.post will do nothing because the req will be destroy after the page is loaded, and res.post does not exist, it does not work that way. You must pass the id and re-find the post with the id. Use req.params.post Commented Oct 11, 2015 at 11:03

2 Answers 2

2

How do I update/upsert a document in Mongoose?

Here is a good start. I personally use the following approach recommended at scotch.io

app.put('url', function(req, res) {

    // use our bear model to find the bear we want
    Bear.findById(req.params.bear_id, function(err, bear) {

        if (err)
            res.send(err);

        bear.name = req.body.name;  // update the bears info

        // save the bear
        bear.save(function(err) {
            if (err)
                res.send(err);

            res.json({ message: 'Bear updated!' });
        });

    });
});

https://scotch.io/tutorials/build-a-restful-api-using-node-and-express-4

Sign up to request clarification or add additional context in comments.

1 Comment

Yup, I can do this by above code, but I actually want to reuse the code for at least getById stuff.
1

Thanks for all the help it was really appreciated, Actually there was a mistake in Mongoose Model in my case posts.js as I need to attach the model after defining method in Post model. The correct one was

var mongoose = require('mongoose');
var PostSchema = new mongoose.Schema({
    title: String,
    link: String,
    upvotes: { type: Number, default: 0 },
    downvotes: { type: Number, default: 0 },
    comments: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Comment' }]
});

PostSchema.methods.upvote = function (cb) {
    this.upvotes += 1;
    this.save(cb);
}

mongoose.model('Post', PostSchema);

As now I put PostSchema.methods.upvote stuff above the mongoose.model('Post',PostSchema);

1 Comment

glad to see you got it worked out. Are you now getting the expected behavior since to added the properties to the post class before declaring the model?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.