Search code examples
mongodbmeteormeteor-blaze

Meteor: Increment DB value server side when client views page


I'm trying to do something seemingly simple, update a views counter in MongoDB every time the value is fetched.

For example I've tried it with this method.

Meteor.methods({
    'messages.get'(messageId) {
        check(messageId, String);

        if (Meteor.isServer) {
            var message = Messages.findOne(
                {_id: messageId}
            );

            var views = message.views;

            // Increment views value
            Messages.update(
                messageId,
                { $set: { views: views++ }}
            );
        }

        return Messages.findOne(
            {_id: messageId}
        );
    },
});

But I can't get it to work the way I intend. For example the if(Meteor.isServer) code is useless because it's not actually executed on the server.

Also the value doesn't seem to be available after findOne is called, so it's likely async but findOne has no callback feature.

I don't want clients to control this part, which is why I'm trying to do it server side, but it needs to execute everytime the client fetches the value. Which sounds hard since the client has subscribed to the data already.

Edit: This is the updated method after reading the answers here.

'messages.get'(messageId) {
    check(messageId, String);

    Messages.update(
        messageId,
        { $inc: { views: 1 }}
    );

    return Messages.findOne(
        {_id: messageId}
    );
},

Solution

  • views++ means:

    1. Use the current value of views, i.e. build the modifier with the current (unmodified) value.
    2. Increment the value of views, which is no longer useful in your case because you do not use that variable for anything else.

    Avoid these increment operator if you are not clear how they exactly work.

    Why not just using a mongo $inc operator that could avoid having to retrieve the previous value?