Gregory Worrall
Gregory Worrall

Reputation: 181

MongoDB update upon button click

Within my view, I am directing the user from '/dashboard' to '/upvote'

Within my routes, I have:

app.get('/upvote', function(req, res) {
        user = req.user
        user.score += 1;
        user.save();
        res.redirect('/dashboard');
    });

This is just an example, trying to grasp how to use this for a different purpose at a later stage.

How do I correctly update my users 'score' attribute to increment every time there's a GET command for '/upvote/' ?

Upvotes: 1

Views: 3072

Answers (2)

JohnnyHK
JohnnyHK

Reputation: 312115

If you separately modify and then save your user document, you can lose votes during concurrent requests.

Instead, use update with the $inc operator to make the upvote atomic:

app.get('/upvote', function(req, res) {
    User.update({_id: req.user._id}, {$inc: {score: 1}}, function(err, count) {
        res.redirect('/dashboard');
    });
});

BTW, you should consider using a POST or PUT request instead of a GET as GET requests shouldn't change data.

Upvotes: 1

Jonah Williams
Jonah Williams

Reputation: 21441

You need to find the given user in your request; req.user is just an object and not a mongoose model. If you have the ID of the document, you can use findById. If you don't you'll need to use a find query on another field.

// Users is the mongoose model
Users.findById(id, function (err, user) {
  if (err) return handleError(err);

  user.score += 1;

  user.save(function(err) {
    if (err) return handleError(err);
    res.send(user); // Or redirect, basically finish request.
  });
});

Second of all - I wouldn't necessarily do a redirect. You could stay on the same page and simply have the command refresh the user model.

Upvotes: 1

Related Questions