pmogollons:collection-hooks

v1.0.3Published last month

Meteor Collection Hooks

Extends Mongo.Collection with onInsert, onUpdate and onRemove hooks.

Getting Started

Installation:

meteor add pmogollons:collection-hooks

All hooks run after the operation has completed, so you can safely modify the document in the hook without affecting the operation.

onInsert

1const removeOnInsert = Collection.onInsert(function ({ userId, doc }) {
2    // Code here run after the insert operation has completed
3}, {
4  // You can set the doc fields the hook will receive. If not set, it will return all fields.
5  docFields: {
6    field1: 1,
7    field2: 1
8  }
9});
10
11// You can remove the hook with the returned function
12removeOnInsert();

onUpdate

1const removeOnUpdate = Collection.onUpdate(function ({ userId, doc, previousDoc }) {
2    // Code here run after the update operation has completed
3}, {
4  // You can set the doc fields the hook will receive. If not set, it will return all fields.
5  docFields: {
6    field1: 1,
7    field2: 1
8  },
9  // If set to true, the hook will receive the previous document
10  fetchPrevious: true
11});
12
13// You can remove the hook with the returned function
14removeOnUpdate();

onRemove

1const removeOnRemove = Collection.onRemove(function ({ userId, doc }) {
2    // Code here run after the remove operation has completed
3}, {
4  // You can set the doc fields the hook will receive. If not set, it will return all fields.
5  docFields: {
6    field1: 1,
7    field2: 1
8  }
9});
10
11// You can remove the hook with the returned function
12removeOnRemove();

onBeforeInsert

1const removeOnBeforeInsert = Collection.onBeforeInsert(function ({ userId, doc }) {
2  // Code here runs before the insert operation has completed. Any changes to the doc are persisted in the db.
3  // You can throw here to cancel the op
4});
5
6// You can remove the hook with the returned function
7removeOnBeforeInsert();

Direct access (circumventing hooks)

1Collection.insertAsync(doc, { skipHooks: true });
2Collection.updateAsync(query, mod, { skipHooks: true });
3Collection.removeAsync(query, { skipHooks: true });

Error handling on hooks (except onBeforeInsert)

Errors thrown inside any hook are caught and emitted as a global event that you can listen to.

1CollectionHooks.onError((err) => {
2  // Do something with the error
3  console.error("Error on hook", err);
4});

Hooks emitter

You can access the emitter directly. Is not recommended to use it unless you know what you are doing.

1CollectionHooks._hooksEmitter;

Why only onBeforeInsert?

Well we didn't had the use case for the other before hooks and didn't want to add more complexity to the package.

Additional notes

  • If you throw an error on the onBeforeInsert hook the insert operation will be cancelled.
  • By default, previousDoc is not fetched on onUpdate. If you want to fetch it, set fetchPrevious to true.
  • If you want to fetch only specific fields on the doc, set the docFields option to the mongo projection you want to fetch.
  • It is quite normal for userId to sometimes be unavailable to hook callbacks in some circumstances. For example, if an update is fired from the server with no user context, the server certainly won't be able to provide any particular userId.
  • Hooks can only be defined on the server.
  • Hooks fetch the docs on insert, update and remove operations. So for each op you will get one more op for fetching docs and one more if you want to fetch the previous doc on update.