Reputation: 2315
In my social app(like as FB) I have a strange need to merge two cursors of the same collection users in one publish!
Meteor server print this error: "Publish function returned multiple cursors for collection users".
Maybe this can not be done in Meteor 0.7.2, perhaps I'm mistaken approach. But I have seen the structure of a cursor is pretty simple as I could make a simple array merge and return back a Cursor?
CLIENT
Meteor.subscribe('friendById', friend._id, function() {
//here show my friend data and his friends
});
SERVER
//shared functions in lib(NOT EDITABLE)
getUsersByIds = function(usersIds) {
return Meteor.users.find({_id: {$in: usersIds} },
{
fields: { // limited fields(FRIEND OF FRIEND)
username: 1,
avatar_url: 1
}
});
};
getFriendById = function(userId) {
return Meteor.users.find(userId,
{
fields: { // full fields(ONLY FOR FRIENDS)
username: 1,
avatar_url: 1,
online: 1,
favorites: 1,
follow: 1,
friends: 1
}
});
};
Meteor.publish('friendById', function(userId) { //publish user data and his friends
if(this.userId && userId)
{
var userCur = getFriendById(userId),
userFriends = userCur.fetch()[0].friends,
retCurs = [];
//every return friend data
retCurs.push( userCur );
//if user has friends! returns them but with limited fields:
if(userFriends.length > 0)
retCurs.push( getUsersByIds(userFriends) );
//FIXME ERROR "Publish function returned multiple cursors for collection users"
return retCurs; //return one or more cursor
}
else
this.ready();
});
Upvotes: 4
Views: 2848
Reputation: 4138
See bold red text in the documentation:
If you return multiple cursors in an array, they currently must all be from different collections.
There is the smart-publish package which adds this ability to use on publish to manage multiple cursors on the same collection. It is relatively new.
Either that or manually manage the cursors by using 'this.added', 'this.removed', and 'this.changed' inside the publish.
Upvotes: 4
Reputation: 2315
SOLUTION
Meteor.publish('friendById', function(userId) {
if(this.userId && userId)
{
var userCur = getFriendById(userId), //user full fields
userData = userCur.fetch()[0],
isFriend = userData.friends.indexOf(this.userId) != -1,
retCurs = [];
//user and his friends with limited fields
retCurs.push( getUsersByIds( _.union(userId, userData.friends) ));
if(isFriend)
{
console.log('IS FRIEND');
this.added('users',userId, userData); //MERGE full fields if friend
//..add more fields and collections in reCurs..
}
return retCurs;
}
else
this.ready();
});
Upvotes: 1