Meteor.publish('workjournals', function() {
var p = Profiles.findOne({userId : this.userId});
return WorkJournals.find({companyId: p.companyId});
});
When I logout from the application – I use the standard accounts-password and accounts-ui packages – I got the following error:
Exception from sub workjournals id FLjAKWZ5uEWfJXQ7s TypeError: Cannot read property 'companyId' of undefined
I20150709-16:51:53.676(2)? at [object Object]._handler (app/server/publications.js:122:31)
I20150709-16:51:53.678(2)? at maybeAuditArgumentChecks (packages/ddp/livedata_server.js:1617:1)
I20150709-16:51:53.678(2)? at [object Object]._.extend._runHandler (packages/ddp/livedata_server.js:950:1)
I20150709-16:51:53.678(2)? at [object Object]._.extend._startSubscription (packages/ddp/livedata_server.js:769:1)
I20150709-16:51:53.679(2)? at [object Object]._.extend.protocol_handlers.sub (packages/ddp/livedata_server.js:582:1)
I20150709-16:51:53.679(2)? at packages/ddp/livedata_server.js:546:1
Any ideas?
Am I supposed to verify whether the Profiles subscription is ready or not before using it in another publication?
[UPDATE]
I just discovered that companyId is null because this.userId is null, which means that the logout procedure has already triggered.
Now my question is, why does Meteor run publications again?
The landing page after the user sign out is index.html – which in my project and includes just the {{> LoginButtons}} and some static content.
yes you can, and publications are executed again because they are invalidated when the data they depend on changes. so when the this.userId changes every subscription that depends on it will run again to make sure you only get to see the allowed data.
Publications are executed again when user logs in or out. This is a Meteor core feature, which is painful and causes several issues (one example here). It does not relate to “the data [a subscription] depend on” (@davidrums) or “Meteor.userId() being reactive” (@khamoud).
Tracker.autorun allows you to run a function that depends on reactive data sources, in such a way that if there are changes to the data later, the function will be rerun.
Meteor.userId()
accounts-base/accounts_client.js, line 11
Get the current user id, or null if no user is logged in. A reactive data source.
Regarding your issue on github, it is a known fact that writing good publications is the key to scaling a meteor app. In your repo for your issue you are subscribing to 10,000 documents which is never a good idea (browsers only have so much space). You are also trying to draw all of them at the same time which is also not a good idea. Writing inefficient code is not a framework problem.
Yes that’s true but when the user on the client changes that’s when it sends a message to the server telling to rerun the publications with/without userId. This is necessary because Meteor.userId() is not available inside a publication. Sometimes you don’t want documents published when there is no current user.
I keep having problems on logout.
The fact that this.userId reactivity gets all your publications rerun on logout makes me think that it’s always better to protect each publication with:
if (!this.userId) return this.ready(); //UPDATED
On the other hand, why would you want to run your publication again on logout?
Do you have any alternative pattern to suggest?