5

Judging from this comment by David Glasser in the GitHub issues:

this.userId is the primary API and Meteor.userId() is syntactic sugar for users new to JavaScript who might not understand the details of successfully using this yet

It seems like we should use this.userId whenever possible (such as inside a method function, where you can use both), and only use Meteor.userId() inside publish functions. If this assumption is correct, why?

(Referring to the relevant bits of the code would also be helpful, I can't seem to find it)

dayuloli
  • 16,205
  • 16
  • 71
  • 126
  • 1
    possible duplicate of [Meteor.userId vs Meteor.userId()](http://stackoverflow.com/questions/24320754/meteor-userid-vs-meteor-userid) – CollinD Sep 26 '15 at 17:57
  • @CollinD That question is with regards to `Meteor.userId` vs `Meteor.userId()`. This question is with regards to `this.userId` vs `Meteor.userId()` – dayuloli Sep 26 '15 at 18:02
  • There is an answer that seems relevant. It specifically references your question. Sorry if it isn't. – CollinD Sep 26 '15 at 18:03
  • @CollinD Thanks for trying to provide a relevant link, but in a method function, where you can use both `this.userId` or `Meteor.userId()`, why choose one over the other? – dayuloli Sep 26 '15 at 18:06
  • Consider performance as a factor. That is the main reason for using this.userId rather than Meteor.userId – Sak90 Sep 26 '15 at 18:09

2 Answers2

15

Your question seems to conflate Meteor.userId() and Meteor.user(). The body of the question seems to be asking about the former while the subject line is asking about the latter. I'll try to address both.

  1. On the server, within a publish function, calling either Meteor.userId() or Meteor.user() will cause an error. Instead, use this.userId or Meteor.users.findOne(this.userId), respectively. However, note that the publish function is only called when a client subscribes. If you want the publication to change when the user record changes, you'll need to observe() the cursor returned by Meteor.users.find(this.userId) and take appropriate action when the record changes.
  2. On the server, while a method call is being processed, Meteor.userId() and Meteor.user() will correspond to the ID of the calling user and their record, respectively. However, be aware that calls to Meteor.user() will result in a DB query because they are essentially equivalent to Meteor.users.findOne(Meteor.userId()).

    Directly within a method call, you can also use this.userId instead of Meteor.userId(), but you are unlikely to see a significant performance difference. When the server receives the method call, it runs your method implementation with the user's ID (and some other info) stored in a particular slot on the fiber. Meteor.userId() just retrieves the ID from the slot on the current fiber. That should be fast.

    It's generally easier to refactor code that uses Meteor.userId() than this.userId because you can't use this.userId outside of the method body (e.g. this won't have a 'userId' property within a function you call from the method body) and you can't use this.userId on the client.

  3. On the client, Meteor.userId() and Meteor.user() will not throw errors and this.userId will not work. Calls to Meteor.user() are essentially equivalent to Meteor.users.findOne(Meteor.userId()), but since this corresponds to a mini-mongo DB query, performance probably won't be a concern. However, for security reasons the object returned by Meteor.user() may be incomplete (especially if the autopublish package is not installed).
Dean Brettle
  • 737
  • 4
  • 10
  • Thanks for the spot, I did mean `Meteor.userId()` and have corrected the question title. Everything in your answer is quite clear and confirms what I have been reading. Would it be possible for you to expand a little on "Since Meteor.userId() will work deeper in the call stack"? In your previous comment, you said "Meteor.userId() doesn't query the DB or consume any significant extra resources." - then what does it do? I haven't been able to find this piece of code in the source code. – dayuloli Sep 27 '15 at 07:37
  • Thanks for the edit, although I can't claim to understand the code you linked to, I do understand a little more how `Meteor.userId()` works now. Also thanks for giving an alternative viewpoint to the comment in the question, that using `Meteor.userId()` may be better because you can port the same code elsewhere, maybe on the client. Thanks again for you answer. – dayuloli Sep 27 '15 at 09:19
1

Simply speaking, Meteor.userId() queries the DB everytime you use it. In client side ( logically ), it looks fine - since we have minimongo.

In server side, using Meteor.userId(), consumes extra resources on SERVER, which, at times is undesired.

Now, this.userId is more over like a session variable m ie it will have a value only when there is a userid attached with the current session. And hence,using 'this' reference wont go and fetch the database everytime, but rather than that it used the active session userId.

Consider performance as a factor. That is the main reason for using this.userId rather than Meteor.userId

Sak90
  • 600
  • 6
  • 19
  • Calling Meteor.user or Meteor.userId from publish functions cause an exception. ie, these are available any where in the server except publish functions, while this.userid is available ANYWHERE. Also, it is clear that Meteor.user Meteor.userId etc fetches the user object from the mongo (via Accounts object ) - See https://github.com/meteor/meteor/blob/devel/packages/accounts-base/accounts_common.js#L222 – Sak90 Sep 26 '15 at 18:21
  • 3
    `Meteor.userId()` doesn't query the DB or consume any significant extra resources. However, on the server, `Meteor.user()` does. – Dean Brettle Sep 27 '15 at 06:48