1

I have a thread model in mongoose, which has an id field of course and an likes field which includes all the users who has liked this thread before so that people can't like the same thread twice.

const ThreadSchema = new mongoose.Schema({
    author: {
        id: { type: ObjectID, required: true, ref: 'User' },
        screen_name: { type: String, required: true },
        picture: { type: String, required: true },
    },
    theme: { type: String },
    text: { type: String, required: true },
    comments: {
        count: { type: Number, default: 0 },
    },
    likes: {
        count: { type: Number, default: 0 },
        users: [{
            _id: false,
            id: { type: ObjectID, ref: 'User' },
            screen_name: { type: String },
            picture: { type: String },
        }],
    },
}, {
    timestamps: true,
});

When I do an update, I will validate the threadID and likes.users.id, and only do the update when the 2 conditions match.

addLike(threadID, user) {
        return new Promise((resolve, reject) => {
            this.updateOne(
                {
                    _id: threadID,
                    'likes.users.id': { $ne: user.id },
                },
                {
                    $push: { 'likes.users': user },
                    $inc: { 'likes.count': 1 },
                },
                { safe: true }
            ).exec()
                .then((result) => {
                    if (result.nModified) {
                        resolve(result);
                    } else {
                        reject(new Error('Already liked or no such thread.'));
                    }
                })
                .catch((err) => {
                    reject(err);
                });
        });
};

It works. And the result I get is something like this:

{ n: 0, nModified: 0, ok: 1 }

I can use nModified to know whether the update happens or not. When nModified = 0 it means nothing changes. Which means either is no thread match threadID or the user.id has already in likes.users.id.

My problem is:

I want to generate a more clear error message rather than 'Already liked or no such thread.' I want to know the which case it is, is it already liked? or is it no such thread.

I know i can achieve this by findById first, check than update. But is there a better solution? Thanks

Albert Gao
  • 3,653
  • 6
  • 40
  • 69
  • It's not an error. This is intentional and actually indicates the supplied `user.id` is in fact already present in the `likes.users.id`. This is clear because of `n: 0` which means nothing was matched. And that is the intention since you do not want to increment the like count nor put the voting using in the array when they are already there. – Neil Lunn Jun 18 '17 at 07:12
  • I'm fairly positive I already pointed you to ["How to Model a “likes” voting system with MongoDB?"](https://stackoverflow.com/a/28006849/2313887) which already does have a pretty detailed account of why this is the case and is intentional. Perhaps you should show a present document you have to modify with this, the data you are sending and what you expect to happen. So you are either passing something wrong, or it's doing exactly what it should. – Neil Lunn Jun 18 '17 at 07:15
  • @NeilLunn Yes, learned a lot through that post, thanks. And it totally works. I just want to make the error message more clear. I mean, customize error at application level. :) – Albert Gao Jun 19 '17 at 07:04
  • Then include some more detail in your question like you were asked to! If you don't understand "why?", then include a sample document and the update parameters you are sending. Then I for one am more than happy to further explain what is happening given that case. Presently your question tells us nothing. That's why it does not have an answer. Provide the data if you want help. Please. – Neil Lunn Jun 19 '17 at 07:06
  • @NeilLunn Sorry for delay, update the question, should be more clear now :) – Albert Gao Jun 21 '17 at 09:38

0 Answers0