Rob Wheatley
Rob Wheatley

Reputation: 11

Problems with reywood: publish-composite. Subscription not updating

It's embarrassing how much time I've spent trying to work this out.

Summary: publish-composite is not reactively updating if the thing you are filtering children on itself changes..

Details I have 2 collections; Projects and Tasks.

Tasks 'belong' to a project. A user can select a project to see all the tasks in it.

Projects can be shared with other users, so user A and user B might be members of the project and both can see all tasks in it.

I'm using Publish Composite to publish the projects and their associated tasks.

All almost works fine. Users see the projects they should see and the tasks within those projects.

However, if a user moves a task from one project to another, server side Mongo is updated as you would expect, but the client side Mini Mongo isn't. It just reverts the task back to the original project and therefore the client side doesn't see that the task has moved project. Well, it does this 90% of the time, sometimes it does what you expect.

Just in case it's my client code causing the problem, I edited the DB directly. All changes are reactively updated on the client, apart from moving tasks from one project to another. In that case, the client isn't told about the change.

Here's my publish code:

  Meteor.publishComposite('projects', function() {

    const userId = this.userId;
    return {
      find() {
        return Projects.find({'memberSettings.memberId':userId}, {fields:{id:1, members:1, title:1, 'memberSettings.$':1 }})
      },
      children: [{
        find(project) {
          return Tasks.find({projectId: project._id, deletedAt:null},
                  {fields: {title:1,
                            projectId:1,
                            userInfo:{$elemMatch:{userId:this.userId}}
                  }})
        }
      },
      ]
    };
  });

There are more task fields published, I just took them out of here for clarity.

So, the Projects find is looking for users who are in the memberSettings array. If they are not a project member, they don't get in. Projects only returns the member settings array element for the logged in user too (part of the field filter).

Once the first bit of code finds all the relevant projects, it then creates children for the tasks in each project. Note how the Tasks find is filtering on projectId to do this.

If anything in the task changes, other than the projectId, all is fine.

But the moment the projectId is changed, the change happens on the server, but not the client (well, most of the time).

If I re-load the page (and renew subscriptions) then the moved task is in the new project like it should have been.

I've done loads of things to try and get to the bottom of this, including removing almost all my other code just in case something I'm doing elsewhere is messing things up, but for the life of me, I can't work out what's going on.

Any pointers would be much appreciated.

Upvotes: 1

Views: 98

Answers (0)

Related Questions