Meteor-Community-Packages / meteor-collection-hooks

Meteor Collection Hooks
https://atmospherejs.com/matb33/collection-hooks
MIT License
658 stars 90 forks source link

Circumventing specific hooks #227

Open mpowaga opened 7 years ago

mpowaga commented 7 years ago

Is there a way to circumvent specific hooks? For example:

test.before.update('resizeImages', function (userId, doc, fieldNames, modifier, options) {
  // ...
});

test.withoutHooks('resizeImages').update({_id: "test"}, {$set: {test: 1}})
zimme commented 7 years ago

test.direct.update

zimme commented 7 years ago

https://github.com/matb33/meteor-collection-hooks#direct-access-circumventing-hooks

zimme commented 7 years ago

Or do you only want to circumventing before and not after for example?

mpowaga commented 7 years ago

Suppose you have two hooks A and B. Direct access will circumvent hooks A and B. In some cases you may want to circumvent only hook A but still run hook B.

zimme commented 7 years ago

To my knowledge this isn't supported. One way to achieve it is to store the handler you get when adding a hook and use that to remove the hook before performing the action and after it's done add the hook once more and save the new handler.

mpowaga commented 7 years ago

Shouldn't this be supported? I think it's pretty common use case. I'd happily send a PR for this.

zimme commented 7 years ago

Let's talk through a possible implementation before the PR?

mpowaga commented 7 years ago

Sure. See my proposed API at the top.

Another solution would be to use reference instead of string, e.g.

const resizeImages = test.before.update(function (userId, doc, fieldNames, modifier, options) {
  // ...
});

test.withoutHooks(resizeImages).update({_id: "test"}, {$set: {test: 1}})
zimme commented 7 years ago

Today when when you do

const beforeInsertPostsHandler = Posts.before.insert((...) => ...);

You get the handler which is an object with remove and replace, maybe we could add collection/direct here and one could then use the beforeInsertPostsHandler.direct.insert(...) to run the insert without this hook.

Edit: this way we don't "pollute" the collection prototype even more.

mpowaga commented 7 years ago

Would test.direct.withoutHooks(resizeImages).update(...) be possible? I think it's more explicit. Also that would allow to disable many hooks at the same time.

zimme commented 7 years ago

Maybe we can support .direct(options), it would be a "breaking" change but there are other potentially breaking changes in 0.9.0-rc4 so I'm thinking it's fine as long as we document the change.