In Meteor.js, Why is this.userId == undefined?

2020-07-18 06:26发布

问题:

I'm learning Meteor by following a book, and right now we want to insert() the userId of the user that is currently logged in.

Template.categories.events({

    'keyup #add-category': function(e, t) {
        if(e.which == 13) {
          var catVal = String(e.target.value || "");
          if(catVal) {
            lists.insert({Category: catVal, owner: this.userId});
            console.log(this.userId);
            Session.set('adding_category',false);
          }
        }
    },

However this.userId was undefined, so the insert() didnt work as expected. What's missing to get this working?

Somehow it works in the code below (userId is defined):

lists.allow({
    insert: function(userId, doc) {
      return adminUser(userId);
    },
    update: function(userId, docs, fields, modifier) {
      return adminUser(userId);
    },
    remove: function(userId, docs) {
      return adminUser(userId);
    }
});

Update

Why is it that on the server-side, this.userId works but not Meteor.userId()?

Meteor.publish("Categories", function() {
    return lists.find({owner:this.userId}, {fields:{Category:1}});
});

回答1:

You should use Meteor.userId() instead.



回答2:

You should use Meteor.userId() everywhere except in the publish function, inside of the publish function only you have to use this.userId.

this.userId is only available on the server. In your methods because of latency compensation the client has access and needs to emulate what the server will do, so if you use this.userId in Meteor.call then the client will fail when it runs them.

The client does not have access to the userId from this.userId, but both client and server (except in publish functions) have access to the current userId through Meteor.userId().

Hope this clarifies it. It took me quite a while to figure this out.

BTW, I know this is a response to an old post, but I had a hard time finding the answer to this, and hopefully this helps someone going through the same thing in the future.



回答3:

For the update question: Meteor.userId can only be invoked in method calls. Use this.userId in publish functions.



回答4:

From my experience, use this.userId on server-only method calls and publish functions to avoid errors. On the other hand, use Meteor.userId() whenever the client is involved (anywhere but the publish functions).



回答5:

this.userId is only available on the server. Meteor user node-fibers when running and you've access to environment attributes. When you're using an NPM package, let's say Stripe, and you want to set a callback you've to use Meteor.bindEnvironment(). The docs aren't that much expressive about this: http://docs.meteor.com/#/full/timers . Also check this question : What's going on with Meteor and Fibers/bindEnvironment()?

At the server, you code must run inside a fiber.

On the client you're not running your code inside a fiber and that's why this.userId is not available.