I'm creating some templates using Template.onCreated, and am then using Tracker.autorun to make some subscriptions and then collect data from the Server and store them on the client's MiniMongo.
Then, I can leave said Template and eventually route myself back. However, I'm noticing that upon coming back, Blaze is not capturing my changes. When routing back, it seems that onRendered is called instead of onCreated. This makes sense, however, onRendered isn't quite reacting to all my data changes yet. I've noticed it's because minimongo doesn't actually have data in it for onRendered.
However, I've noticed it can get the object by refreshing the page (thus calling onCreated and subscribing again and getting a fresh set of data from the server) My workaround is to re-subscribe in onRendered, but I feel like i shouldn't have to do this because I already initially subscribed in OnCreated. Is this an issue with Meteor, is DDP just going slow?
Let's say I have some default generic collection called Objects.
const Objects = new Mongo.Collection("Objects");
So in my onCreated I subscribe to a collection as follows
Template.foo.onCreated(function () {
var self = this;
self.autorun(function () {
const objId= FlowRouter.getParam("id");
self.objectSubscription = Meteor.subscribe('obj', objId, {
onReady: function () {
},
onStop: function (error) {
if (error) {
alert('error')
}
}
});
Then in onRendered I have to hack it and unnecessarily re-subscribe because I don't have objId i.e. I can't just use Objects.find(),
Template.foo.onRendered(function () {
const objId= FlowRouter.getParam("id");
Meteor.subscribe('obj', objId, {
onReady: function () {
$('#obj').addClass('highlight');
},
onStop: function (error) {
if (error) {
alert('error');
}
}
});
//I feel like I should just be able to do
//const obj = Objects.findOne({_id:objId})
//$('#obj').addClass('highlight')
});
Any insights, why would I be losing data in minimongo? And is it bad practice to "re-subscribe"?
onCreated
and onRendered
aren't reactive, but template helpers
are. So, to constantly detect changes in those two you'd have to create a reactive context and place it inside them which can be achieved using Tracker.autorun
. Also, be advised that it's better to keep onRenderd
for DOM manipulations and onCreated
for subscriptions and creation of reactive variables
.
You don't need double subscriptions to detect changes and IMO this is generally a bad practice.
Template.foo.onCreated(function onCreated() {
const self = this;
this.autorun(function() {
const id = FlowRouter.getParam('_id');
self.subscribe('obj', id);
});
});
Template.foo.onRendered(function onRendered() {
const self = this;
// this will run after subscribe completes sending records to client
if (self.subscriptionsReady()) {
// do whatever you want
$('#obj').addClass('highlight');
}
});