meteor-collection-hooks icon indicating copy to clipboard operation
meteor-collection-hooks copied to clipboard

Hooks don't work inside observeChanges

Open dovrosenberg opened this issue 9 years ago • 6 comments

I have a collection with a find hook attached to it. Inside of a meteor.publish, I have an observeChanges callback that is effectively doing a reactive join. The problem is that inside that callback, the find call always returns nothing. It appears to be because the userId isn't being properly retrieved inside the callback.

Meteor.publish('sample', function(id) {
var self = this;

var list1 = Collection1.find({_id:id});
var IDs = _.pluck(list1.fetch(), 'refID');

Collection2.find().count();  // this works fine

var handle = Collection1.observeChanges({
    added: function(id, fields) {
        Collection2.find().count();  // this always returns zero records
        self.added('contacts', fields.refID, Collection2.direct.findOne(fields.refID));  // this works fine
    }
});

// stop observing changes when publish ends
self.onStop(function() {
  return handle.stop();
});

self.ready();

return [list1, Collection2.find({_id:{$in:IDs}})];
});

Using the direct call works fine for my use case, but this seems like a bug, no?

dovrosenberg avatar Sep 07 '15 18:09 dovrosenberg

Note that in a method call, I think this might be because Meteor.bindEnvironment doesn't work properly inside observeChanges; I've seen some issues related to this such as meteor/meteor#907 and meteor/meteor#3455.

However, I see you're using a publish function (instead of a method call) there; that definitely won't work because we use a monkey-patch to store the userId during the publish and it will be forgotten when the callback is used. (https://github.com/matb33/meteor-collection-hooks/blob/master/collection-hooks.js#L268)

The problem is that the callback doesn't know it was started during the publish context, and has no idea what user it is supposed to supply to the find hook, so the find hook basically gets no user. The solution is to either set up the find without the hook after binding the userId in the closure yourself - you can use the hook anywhere else outside of publish functions.

Also, you might want to check out https://github.com/mizzao/meteor-partitioner if you're not using it already.

mizzao avatar Sep 08 '15 20:09 mizzao

Makes sense. Thanks. Should meteor-partitioner solve this issue (great package, by the way)? I am using a fork of it customized for my particular application, and it's a partitioned collection that is displaying this behavior. But perhaps I cut out some important code in my customization?

dovrosenberg avatar Sep 08 '15 20:09 dovrosenberg

Is there a workaround that will accomplish the same thing? I don't understand the one mizzao said.

turbobuilt avatar Nov 03 '16 21:11 turbobuilt

I could only work around it using .direct like above and then handling the transforms that the find hook would normally do manually.

dovrosenberg avatar Nov 04 '16 17:11 dovrosenberg

Bummer. Thanks for letting me know though.

turbobuilt avatar Nov 05 '16 15:11 turbobuilt

~~From the first code example in this issue I believe this might be related to #215.~~

zimme avatar Feb 04 '17 23:02 zimme