I have two collections items
and worksheet
.
Each worksheet has an item
array field where I store all the worksheet items
_id. Based on this field, I publish items for the current worksheet. The publication looks like that:
Meteor.publish("get_items", function(worksheetId) {
var currentWorksheet = Worksheets.findOne(worksheetId);
if (currentWorksheet.items) {
return Items.find({"_id":{$in:currentWorksheet.items}}, {});
} else {
console.log("no item to send");
return Items.find({"_id":null}, {});
}
}
return this.ready();
});
This publication is subscribed in the current page iron-router controller.
Here is the problem:
I use a dedicated component with a template level subscription in order to change the current worksheet items
field. This component is loaded in a bootbox.
When I change the current worksheet items
field, my main publication does not update to take the changes into account. However, if I reload the page, the changes are taken into account.
How should I design my publication so that it stays reactive despite having a dependency on another collection?
You can use Meteor.publishComposite() as follows
Meteor.publishComposite('itemsByWorksheet', function (params) {
check(params, {
worksheetId: String
});
var worksheetId = params.worksheetId;
return {
find: function () {
return Worksheets.find({ worksheetId: worksheetId })
},
children: [
{
find: function (worksheet) {
return Items.find({_id: {$in: worksheet.items}})
}
}
]
}
});
This will create a reactive publication that will subscribe to items based on the changes in the original worksheet publication.
You will need the following package from atmosphere for this solution: https://atmospherejs.com/reywood/publish-composite
Your subscription would look like this:
Meteor.subscribe('itemsByWorksheet', {worksheetId: "<worksheet id goes here>"});