Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to 'transform' data returned via a Meteor.publish?

Tags:

meteor

Meteor Collections have a transform ability that allows behavior to be attached to the objects returned from mongo.

We want to have autopublish turned off so the client does not have access to the database collections, but we still want the transform functionality.

We are sending data to the client with a more explicit Meteor.publish/Meteor.subscribe or the RPC mechanism ( Meteor.call()/Meteor.methods() )

How can we have the Meteor client automatically apply a transform like it will when retrieving data directly with the Meteor.Collection methods?

like image 845
Pat Avatar asked Jan 03 '14 01:01

Pat


People also ask

How does meteor publishing work?

In Meteor a publication is a named API on the server that constructs a set of data to send to a client. A client initiates a subscription which connects to a publication, and receives that data.

What is Meteor publish?

To publish records to clients, call Meteor. publish on the server with two parameters: the name of the record set, and a publish function that Meteor will call each time a client subscribes to the name. Publish functions can return a Collection.


2 Answers

While you can't directly use transforms, there is a way to transform the result of a database query before publishing it. This is what the "publish the current size of a collection" example describes here.

It took me a while to figure out a really simple application of that, so maybe my code will help you, too:

Meteor.publish("publicationsWithHTML", function (data) {
    var self = this;
    Publications
        .find()
        .forEach(function(entry) {
            addSomeHTML(entry);  // this function changes the content of entry
            self.added("publications", entry._id, entry);
        });
    self.ready();
});

On the client you subscribe to this:

Meteor.subscribe("publicationsWithHTML");

But your model still need to create a collection (on both sides) that is called 'publications':

Publications = new Meteor.Collection('publications');

Mind you, this is not a very good example, as it doesn't maintain the reactivity. But I found the count example a bit confusing at first, so maybe you'll find it helpful.

like image 113
Christian Fritz Avatar answered Sep 22 '22 03:09

Christian Fritz


Try:

let transformTodo = (fields) => {
  fields._pubType = 'todos';
  return fields;
};

Meteor.publish('todos', function() {
  let subHandle = Todos
    .find()
    .observeChanges({
      added: (id, fields) => {
        fields = transformTodo(fields);
        this.added('todos', id, fields);
      },
      changed: (id, fields) => {
        fields = transformTodo(fields);
        this.changed('todos', id, fields);
      },
      removed: (id) => {
        this.removed('todos', id);
      }
    });
  this.ready();
  this.onStop(() => {
    subHandle.stop();
  });
});
like image 41
HaNdTriX Avatar answered Sep 23 '22 03:09

HaNdTriX