So I have a Meteor app that has a cron job running where every 1 minute it runs a bunch of calculations, insert the results on the DB and I want those results to be immediately published on the client.
I created the pub/sub model only to find out that MeteorJs does not reactivity in this model (do please correct me if I am wrong).
Template.Main.onCreated(function bodyOnCreated() {
Meteor.subscribe('arb', {
onReady: function () { console.log("onReady And the Items actually Arrive", arguments); },
onError: function () { console.log("onError", arguments); }
});
});
So when I load the page, I can see the onReady() function being called. I would expect to see that log being written every 1 minute. But it is not happening and the data is not being pushed to the client every minute.
Meteor.publish('arb', function () { // Why itemsPublication ?
this.autorun(function () { // No need Computation in your case ?
return Item.find({});
});
});
Yeah - you’re wrong - Meteor’s pub/sub model is expressly designed for reactivity. When used with MongoDB you get reactivity out of the box.
The template onCreated and onRendered lifecycle methods are only ever called once per template instance (btw, you should be using this.subscribe rather than Meteor.subscribe in your onCreated to get automatic lifecycle management of your subscriptions).
Reactivity in this use case comes from using template helpers. I recommend reading the Meteor Guide ahead of the API docs:
@Vandell: Using an autorun in a publication is discouraged (it’s not even documented). In a pub/sub context, they’re intended for subscriptions - and only then if the subscription has reactive parameters. Again, using Tracker directly is way beyond what’s needed here.
When I add this.autorun(function () to my publish function, I am not getting the publishing at all in the client. The onReady() function does not get called.
When I remove the autorun, I do get the onReady(), but the changes on the model are not getting reflected.
Hi Rob, thank you for helping me out. I am only but new with Meteor, this is my first project. Do please excuse my general ignorance.
So here’s what I have so far:
In /server/publications/item.js:
import { Meteor } from 'meteor/meteor';
import Item from '../../lib/collections/item.js';
Meteor.publish('arb', function() {
return Item.find({});
});
In /client/templates/home/home.js
import { Template } from 'meteor/templating';
import { Session } from 'meteor/session'
import Item from '../../../lib/collections/item.js';
Template.Main.onCreated(function bodyOnCreated() {
});
Tracker.autorun(() => {
Meteor.subscribe('arb', {
onReady: function () { console.log("onReady And the Items actually Arrive", arguments); },
onError: function () { console.log("onError", arguments); }
});
});
Template.Main.helpers({
btcmindy() {
return Item.findOne({key: {$eq: 'btcmindy'} });
},
});
Now, I am expecting to see the “onReady” function being called every minute, in other words, every time a new insert is done in the model. But this is not happening.
Once the subscription is set up (ready) it will not be run again.
I would start simple. Your publication is fine. It returns the entire collection, which is okay if it’s reasonably small (less than a few hundred docs).
The btcmindy helper will rerun whenever the document located by key: 'btcmindy' changes. If that document never changes, the helper will not rerun.
If you are adding many documents with a key of 'btcmindy' you should be using find, not findOne in your helper.
You need to use a Blaze template to see the results (or you could console.log in the helper code).
You should be importing { Item }, not Item. Also, see the next point.
You are importing from lib/ - that’s actually unnecessary - files in lib/ are always loaded on both client and server. I’d be inclined to create imports/both/collections/ and put your item.js in there. Then do import { Item } from '/imports/both/collections/item'; in your client and server modules - it’s easier to grok than ../../...