Meteor - 如何在不引发错误的情况下查看是否可以使用Meteor.user()?

时间:2014-11-19 12:45:04

标签: javascript meteor

我正在寻找一种方法来确定Meteor.user()是否设置在一个可以从服务器端和客户端调用的函数中,而不是在没有引发错误的情况下调用错误。

在我的具体情况下,如果没有设置,我使用Meteor服务器的启动功能来创建一些虚拟数据。此外,我使用Collection2-package的autoValue函数根据当前登录用户的配置文件创建一些默认属性(如果可用)。

所以我在服务器代码中有这个:

Meteor.startup(function() {
    if (Tags.find().fetch().length === 0) {
        Tags.insert({name: "Default tag"});
    }
});

在Tags-collection的架构中:

creatorName: {
    type: String,
    optional: true,
    autoValue: function() {
        if (Meteor.user() && Meteor.user().profile.name)
            return Meteor.user().profile.name;
        return undefined;
    }
}

现在启动服务器时,如果不存在任何标签,则会引发错误:Meteor.userId can only be invoked in method calls. Use this.userId in publish functions.

因此换句话说,在服务器启动时调用Meteor.user()会抛出错误,而不是返回undefined或null或其他内容。 有没有办法在调用之前确定是否会这样做?

我无法简单地通过在autoValue函数中使用if (Meteor.isServer)包装调用来解决这个问题,因为autoValue函数通常从服务器端调用,即使在用户调用时也是如此,在这些情况下,我的代码中的所有内容都能正常工作

请注意,这与How to get Meteor.user() to return on the server side?有关,但这并不涉及检查Meteor.user()是否可用于调用它可能会或可能不会导致错误的情况。

2 个答案:

答案 0 :(得分:2)

在服务器上,Meteor.users只能在方法的上下文中调用。因此,它在Meteor.startup中无法工作是有道理的。不幸的是,警告信息并不是很有帮助。您有两种选择:

尝试/捕获

如果从错误的上下文调用错误,您可以修改autoValue以捕获错误:

autoValue: function() {
  try {
    var name = Meteor.user().profile.name;
    return name;
  } catch (_error) {
    return undefined;
  }
}

我认为如果{0}在您的虚拟数据中是可接受的名称,这是有道理的。

跳过生成自动值

因为您知道undefined总是会失败(即使它没有,但它不会添加有用的值),您可以skip generating automatic values进行这些插入。如果您需要创建者的真实姓名,您可以从现有数据库中选择一个随机值(假设您已经填充了一些用户)。

答案 1 :(得分:2)

已经坚持了两天,这就是最终让我的工作:

解决方案:使用服务器端会话来阻止userId

  

“Meteor.userId只能在方法调用中调用。在发布函数中使用this.userId。”

错误,因为使用 this.userId 会返回null。

LIB /模式/ schema_doc.js

//automatically appended to other schemas to prevent repetition
Schemas.Doc = new SimpleSchema({
createdBy: {
    type: String,
    autoValue: function () {
        var userId = '';

        try {
            userId = Meteor.userId();
        } catch (error) {
            if (is.existy(ServerSession.get('documentOwner'))) {
                userId = ServerSession.get('documentOwner');
            } else {
                userId = 'undefined';
            }
        }

        if (this.isInsert) {
            return userId;
        } else if (this.isUpsert) {
            return {$setOnInsert: userId};
        } else {
            this.unset();
        }
    },
    denyUpdate: true
},
// Force value to be current date (on server) upon insert
// and prevent updates thereafter.
createdAt: {
    type: Date,
    autoValue: function () {
        if (this.isInsert) {
            return new Date;
        } else if (this.isUpsert) {
            return {$setOnInsert: new Date};
        } else {
            this.unset();
        }
    },
    denyUpdate: true
},
//other fields here...
});

服务器/ methods.js

Meteor.methods({
    createPlant: function () {
        ServerSession.set('documentOwner', documentOwner);

        var insertFieldOptions = {
            'name' : name,
            'type' : type
        };

        Plants.insert(insertFieldOptions);
    },
    //other methods here...
});

请注意,我正在使用ff: