0

I implemented a hook function, where I attach some createdAt and updatedAt fields to the doc that is inserted to a collection. I can attach this to any collection like this:

export const insertHook = function (doc) {
    try {
        const user = Meteor.user();
        doc.createdBy = user && user._id ? user._id : null;
        doc.createdAt = new Date().getTime();
    } catch (e) {
        console.err(e);
    }
};

Attaching the hook to the collection is basically passing it via a third option in the constructor:

class HookedCollection extends Mongo.Collection {

    constructor(name, options, hooks={}) {
        super(name, options);
        this.insertHook = hooks.insertHook;
    }

    insert(doc, callback) {
        if (this.insertHook && Meteor.isServer)
            this.insertHook.call(this, doc);
    }
}

export const MyDocs = new HookedCollection("mydocs", {}, {insertHook});

In a Meteor method I just do a normal insert:

Meteor.methods({
    insertDoc:function(doc) {
        //check doc...
        return MyDocs.insert(doc);
    }
});

Which creates basically the following error:

Error: Meteor.userId can only be invoked in method calls or publications.

I tried several ways of bind but always ended up in this error. Is there really no way at all to bind the userId to the function?

Jankapunkt
  • 8,128
  • 4
  • 30
  • 59
  • You're referencing `Meteor.user()` but you don't need the whole user object, just the `_id`. Try `this.userId` or `Meteor.userId()` – Michel Floyd Nov 23 '17 at 01:45

1 Answers1

1

According to Meteor docs Meteor.userId() is available anywhere but publish functions (Server side Publish function).

You aren't using Meteor.userId() directly in the method but in a callback (see discussion in this github issue). You can pass the userId information to your callback function as a parameter from the method, for example:

// Using Meteor.userId()
Meteor.methods({
    insertDoc:function(doc) {
        //check doc...
        return MyDocs.insert(doc, Meteor.userId());
    }
});

// Or using this.userId
Meteor.methods({
    insertDoc:function(doc) {
        //check doc...
        return MyDocs.insert(doc, this.userId());
    }
});

As a general rule use Meteor.userId() in the client (that queries the database) and this.userId in the server. More information in this other question Meteor - Why should I use this.userId over Meteor.userId() whenever possible? and in Meteor forums

Violeta
  • 140
  • 1
  • 8