Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add computed fields to Meteor.users in a publication

Tags:

meteor

I am trying to publish a custom computed field isFriend in publication that returns a record from Meteor.user.

I tried various solutions but none of them seen to work:

  • Transform from a publication does not work as described here ... https://stackoverflow.com/a/18344597/644081

  • I tried the solution here How can I add temp. fields to a Meteor publish .. buy doesn't work either ... see code below

Code:

Meteor.publish("viewProfile", function(id) {
  console.log("Finding the user: " + id);
  var self = this;
  Meteor.users
      .find({"_id": id})
      .forEach(function(entry) {
          entry.isFriend = true;  // this function changes the content of entry
          self.added("Meteor.users", entry._id, entry);
      });
    self.ready();
});

Please advise.

like image 707
Santosh Avatar asked Nov 20 '25 21:11

Santosh


1 Answers

The easiest way to transform a document is to add a transform option to your collection. You can do this directly with the meteor API, or with a package like collection-helpers (see the docs for more details).

However, sometimes you need to transform documents before they get published because only the server has the necessary information. A good example is a signed URL. In this case you can use an observe or an observeChanges to manipulate each object.

observeChanges is much more efficient but it can only operate on partial documents (e.g. if you wanted to transform a single field that already exists). In your example, you need to see the entire document in order to add the field, so you need an observe. Give the following a try:

Meteor.publish('viewProfile', function(userId) {
  check(userId, String);

  // modify this as needed
  var transform = function(user) {
    user.isFriend = true;
    return user;
  };

  // only publish the fields you really need
  var fields = {username: 1, emails: 1, profile: 1};

  var self = this;

  var handle = Meteor.users.find(userId, {fields: fields}).observe({
    added: function (user) {
      self.added('users', user._id, transform(user));
    },

    changed: function (user) {
      self.changed('users', user._id, transform(user));
    },

    removed: function (user) {
      self.removed('users', user._id);
    }
  });

  this.ready();

  this.onStop(function() {
    handle.stop();
  });
});
like image 163
David Weldon Avatar answered Nov 23 '25 04:11

David Weldon