Reputation: 6039
This Meteor code is working fine, but I would like to ask if it is the way Meteor does things or it is a un predictable side effect that may change under some condition later.
The things is that when I do
DisplayCol.insert({action: 'task1', element: 'p', value: value_variable});
Meteor also inserts the correct userId (using 2 different browsers logged in as 2 different users) which I did not explicitly included in the document.
The above line of code is inside a server side function which is called from Meteor method.
here is the relevant information;
//lib/collection.js
DisplayCol = new Mongo.Collection('displayCol');
//server.js
Meteor.publish('displayCol', function () {
return DisplayCol.find({userId: this.userId});
});
DisplayCol.before.insert(function (userId, doc) {
doc.userId = userId;
});
In the docs of Collection hooks > Additional notes > second bulleted paragraph says:
userId is available to find and findOne queries that were invoked within a publish function.
But this is a collection.insert. So should I explicitly include the userId in the document or let the collection hook do its hidden magic? Thanks
Upvotes: 1
Views: 79
Reputation: 2677
No, there is no hidden magic in that code, your before
hook is inserting the userId
field in the document.
When you do an insert
like this,
DisplayCol.insert({action: 'task1', element: 'p', value: value_variable});
the doc
that your are inserting is { action: 'task1', element: 'p', value: value_variable }
Because, you have this hook,
DisplayCol.before.insert(function (userId, doc) {
doc.userId = userId;
});
it changes the doc
before inserting into collection. So the above hook will change your doc
to {action: 'task1', element: 'p', value: value_variable, userId: 'actual-user-id' }
This is the expected behaviour.
Regarding your other point in the question,
userId is available to find and findOne queries that were invoked within a publish function.
Previously userId
parameter in the find
and findOne
returns null
, so user needs to pass userId
as a parameter as mentioned in this comment. Additional notes mentions that the hack is not required any more. It has nothing to do with inserting userId
field into the collection document.
To have a quick test, remove the DisplayCol.before.insert
hook above, you will not see userId
field in the newly inserted documents.
UPDATE
Just to clarify your doubt further, from the 4th point in the docs that you provided
It is quite normal for userId to sometimes be unavailable to hook callbacks in some circumstances. For example, if an update is fired from the server with no user context, the server certainly won't be able to provide any particular userId.
which means that if the document is inserted or updated on the server, there will be no user associated with the server, in that case, userId will return null.
Also you can check the source code yourself here. Check the CollectionHooks.getUserId
method, it uses Meteor.userId()
to get the userId
.
CollectionHooks.getUserId = function getUserId() {
var userId;
if (Meteor.isClient) {
Tracker.nonreactive(function () {
userId = Meteor.userId && Meteor.userId(); // <------- It uses Meteor.userId() to get the current user's id
});
}
if (Meteor.isServer) {
try {
// Will throw an error unless within method call.
// Attempt to recover gracefully by catching:
userId = Meteor.userId && Meteor.userId(); // <------- It uses Meteor.userId() to get the current user's id
} catch (e) {}
if (!userId) {
// Get the userId if we are in a publish function.
userId = publishUserId.get();
}
}
return userId;
};
Upvotes: 2