I'm using some form inputs to create a new Student
with the following code:
var student_id = Students.insert({firstname: firstInput, lastname: lastInput, price: priceInput});
Meteor.users.update({_id: Meteor.userId()}, {$push: {'student_ids': student_id}});
I have the following subscriptions and publications set up:
// On the client.
Meteor.subscribe('currentUser');
// On the server.
// I know this is ugly, but I need to do quite a bit of joining.
Meteor.publish('currentUser', function() {
if (!this.userId) return;
var userCursor = Meteor.users.find({_id: this.userId}, { fields: {firstname: true, lastname: true, student_id: true, student_ids: true, payment_ids: true, phones: true }});
var user = userCursor.fetch()[0];
if (user.student_ids || user.payment_ids) {
var student_ids = user.student_ids || [];
var studentCursor = Students.find({_id: {$in: student_ids}});
var payment_ids = user.customer.payment_ids || [];
var paymentCursor = Payments.find({_id: {$in: payment_ids}});
var lesson_ids = [];
var expense_ids = [];
studentCursor.forEach(function(doc) {
lesson_ids.concat(doc.lesson_ids);
expense_ids.concat(doc.expense_ids);
});
var lessonCursor = Lessons.find({_id: {$in: lesson_ids}});
var expenseCursor = Expenses.find({_id: {$in: expense_ids}});
return [userCursor, studentCursor, lessonCursor, expenseCursor, paymentCursor];
}
else return userCursor;
});
The problem is that one of my {{#each}}
blocks is listing all of these students, and it works fine, except that it doesn't show the new student until the page is refreshed/restarted etc. The publish/subscribe pair isn't being reactive.
I'm not sure how to elegantly solve this problem. I definitely would prefer not to mess with added
and other such callbacks in the publish function. It seems my collections should handle this behavior on their own.
Thanks in advance!
Update
I changed my publish to use publish-with-relations
, a reactive join package, and it now looks like this:
Meteor.publish('currentUser', function() {
var studentMappings = [{
key: 'lesson_ids',
collection: Lessons,
},{
key: 'expense_ids',
collection: Expenses,
}];
return Meteor.publishWithRelations({
handle: this,
collection: Meteor.users,
filter: this.userId,
options: { fields: {firstname: true, lastname: true, student_id: true, student_ids: true, payment_ids: true, phones: true }},
mappings: [{
key: 'student_id',
collection: Students,
mappings: studentMappings
},{
key: 'student_ids',
collection: Students,
mappings: studentMappings
},{
key: 'payment_ids',
collection: Payments,
}]
});
});
Everything gets published, but it still isn't reactive! When the page is freshly reloaded, everything is there as expected, but immediately after adding a new student, there is only a flicker where that student would be (I suspect this is latency compensation at work).
When I query Meteor.user()
in the console, the student_ids
array is correct:
student_ids: Array[1]
0: "5dafpCD7XGcBnyjWd"
length: 1
and when I meteor mongo
this:
meteor:PRIMARY> db.students.find()
{ "firstname" : "Sterling", "lastname" : "Archer", "price" : "22.50", "_id" : "5dafpCD7XGcBnyjWd" }
everything is also correct, but still the document doesn't show up until a page refresh.
Wasn't publish-with-relations
supposed to solve this problem?