Advanced publications


#1

Hello -

I have a publication of Contacts, that I update asynchronously from a Google Apps script. This collection´s documents have Name, Phone and Groups. Groups is an array of strings.

I want to create a new “synthetic” collection (that does not exist on the db) that contains all the unique groups from the Contacts collection.

in /lib/collections/contacts.js i have

Groups = new Mongo.Collection('groups', {connection: null});

and in /server/publications.js

Meteor.publish('groups', function() {
  var groups = []
  Contacts.find().fetch().map(function(x) {groups = _.union(groups,x.Groups)});
  return groups;
}

… which raises an exception “Publish function returned an array of non-Cursors”.

The whole reason why I need this collection is to populate a drop-down box in the UI, and having this in a collection should make my life easier.

Questions:

(1) is there a better/faster/smarter way to do this?
(2) how to fix this?

Best regards,

OP


#2

edit my last solution wouldn’t work… you need to manually send the data down with something like this:

Meteor.publish('groups', function() {

  Contacts.find().fetch().map(function(doc){
    var newDoc = doStuff();
    this.added('groups', doc._id, newDoc);
  }, this)

  this.ready();
})

This should send down a new doc with each loop


#3

I find these two articles from @dburles great


#4

The final form of this function became is below. It should be reactive, and while the loop is probably not very efficient, it works! I can live without the changed and removed handlers events.

Meteor.publish('groups', function() {
  var self=this;
  var groups = [];

  var handle = Contacts.find().observeChanges({
    added: function(id, ctc) {
      groups = _.union(groups,ctc.Groups)
    }
  })

  _.each(groups, function(group) {
    self.added('groups', Random.id(), {"groupname": group});
  });

  self.ready()
});

Thank you @serkandurusoy and @SkinnyGeek1010 for directions!