Search code examples
mongodbmeteorminimongo

In Meteor, a MongoDB update is not seen in the Mongo shell


This is a very odd problem.

I am running a cursor.observe() in a Tracker.autorun(), but the changes are only occurring when I refresh the page. Here is the imporant code:

Client Side

Tracker.autorun(function (){
  var initializing = true;
  Links.find().observe({
    added: function(doc){
        var parents = Links.find({stacks: {$exists: true, $not: {$size: 0}}});
        //Find the parent of this item with a stack array
        if(!initializing){
            _.each(parents.fetch(), function(parentDoc){
                _.each(parentDoc.stacks, function (stackId){

                    //The troublesome server call
                    Meteor.call("addLinksFromDirToStack", 
                      stackId, parentDoc.shared[0].id, parentDoc._id);

                });
              });
          }
      initializing = false;
    }
  });
});

Server Side

Meteor.methods({
  addLinksFromDirToStack: function(stackId, userId, dirId){
        var stack = Stacks.findOne(stackId);
        if (stack){
            var webArray = stack.webArray;
            webArrayFiller(dirId, webArray);
            Stacks.update(stackId, {$set: {webArray: webArray}});
            Stacks.update(stackId, {$addToSet: {users: userId}});
        }
        // NOTE: IF I QUERY THE STACKS COLLECTION HERE, I SEE THE CHANGES
    }
});

webArrayFiller = function(dirId, webArray){
    //Update array
}

As commented above, If I query the Stacks collection directly after my update, the changes are reflected in the database. However, querying from the Mongo Shell, I still see the old Stack, without the update. And this is case on the client side, where the changes should be displayed.

I have tried a Meteor Reset to no avail. Any help would be much appreciated.


Solution

  • I figured out why it wasn't working.

    I wasn't publishing every field of the Stacks collection. In particular, not the users field. Thus when I would attempt to change the collection with this line, it would fail:

    Stacks.update(stackId, {$addToSet: {users: userId}});
    

    However, Minimongo recognized the change, and so my queries would falsely show me I had succeeded. Once the server rejected the update, it would also reject the line directly above, making both changes not occur. Apparently, some find MongoDB's lack of error messages in failed transactions troublesome. It definitely made this error hard to find.

    The solution was to wrap the server side code in a if (Meteor.isServer) so that it would only be run on the server side. An unfortunate consequence is that values cannot easily be returned from these calls, due to asynchronicity, but there are workarounds for that.