Search code examples
javascriptmeteorcollectionsmerge

meteor merging cursors of same collection


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();
});

Solution

  • 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();
    });