我正在寻找一种方法来确定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()是否可用于调用它可能会或可能不会导致错误的情况。
答案 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: