Modify data in Meteor.publish before sending to client
I have the following use case:
- I have a users table in MongoDB on the backend, which is a separate service than the frontend. I am using DDP.connect () to connect to this backend service.
- Each user has a set of "subjects"
-
Every object in the users table is referenced by id, not name. There is a separate table called "subjects" in which subjects have an identifier.
-
I want to publish the user to the client, however . I want the published user to be populated with items first.
I've tried the following, inspired by this blog post :
// in the backend service on port 3030
Meteor.publish('users', function(userId) {
var _this = this;
Meteor.users.find({
_id: userId
}).forEach(function(user) {
user.profile = populate(user.profile);
console.log(user);
_this.changed('users', userId, {
_id: userId,
profile: user.profile
});
});
_this.ready();
});
// in the client
var UserService = DDP.connect('http://localhost:3030');
var UserServiceProfile = UserService.subscribe('users', Meteor.userId());
console.log(UserServiceProfile);
This gives the following error on the server: Exception from sub users id akuWx5TqsrArFnQBZ Error: Could not find element with id XhQu77F5ChjcMTSPr to change
.
So I tried changing _this.changed
to _this.added
. I am not getting any errors, but the changes are not showing in the minimal client, although I can see the function is populate
running through the line console.log(user)
.
source to share
I'm not sure how you will fix your code, but you may not need to. It looks like you need the https://atmospherejs.com/maximum/server-transform package .
Add the server-transform package to your project and replace it with code (I assume you also added an underscore to your project and the collection of objects in your database matches a global variable named Subjects in your code.):
Meteor.publishTransformed('users', function(userId) {
return Meteor.users.find({
_id: userId
}).serverTransform({
'profile.subjects': function(doc) {
var subjects = [];
_(doc.profile.subjects).each(function(subjectId) {
subjects.push(Subjects.findOne(subjectId));
});
return subjects;
}
});
});
source to share