confusion about findOne() and remove()

时间:2016-07-11 20:33:35

标签: node.js mongoose

In my understanding, the below code will delete the document and also return it as the second argument to the callback. is this true? I'm finding alot of conflicting information on the internet. I've used similar approach before but if there is a better approach i am willing to adapt that. I need to delete the document and also access two of its fields: _id and conversation respectfully. thanks, i'll hang up and listen.

deleteMessage: function(userId,messageId,callback){

    model.Message.findOne({_id: messageId, user: userId}).remove().exec(function(err,removed){
        // removed should be the deleted document or some falsey value
        if(err || !removed){
            return callback('Invalid messageId or user does not have permission to delete this message',null);
        }
        callback(null,'Message Deleted');//success

        //we have access to the removed document, so we can get the conversation id easily and emit to the users.
        io.to('convo_'+removed.conversation.toString()).emit('messaging.messageDeleted',{ message: removed._id.toString() });

    });

},

To clarify This is an abstract controller interface for used by more implementation specific apis. basically it normalizes this operation accross any protocols we are supporting or will support in the future.

Here's an example of how this method is used from socket.io:

socket.on('messaging.deleteMessage',function(data){
    var mid = data.message || false;
    MessagingAPI.deleteMessage(user.id,mid,function(err,results){
        socket.emit('messaging.deleteMessage',{error:err,results: results});
    }); 
});

so yes, any updates this controller method sends do belong in the method and not in the callback. the callback is only for the initiator. nothing else.

1 个答案:

答案 0 :(得分:0)

Your method is absolutely correct but IMHO I would prefer doing this way. Looks more logical and sequential.

deleteMessage: function(userId,messageId,callback){
    model.Message.findOne({_id: messageId, user: userId}).remove().exec(function(err,removed){
        // removed should be the deleted document or some falsey value
        if(err || !removed){
            return callback('Invalid messageId or user does not have permission to delete this message',null);
        }
        callback(null, removed);
    });
}

function callback(err, msg) {
    if (err) {
         throw err;
    }
    io.to('convo_'+removed.conversation.toString()).emit('messaging.messageDeleted',{ message: removed._id.toString() });
}

I feel that once you call the callback, there shouldn't be anything following it. Else it becomes really difficult to track both the callback function and post-callback execution.