Adam Monsen
Adam Monsen

Reputation: 9430

How can I get the name of the currently executing Meteor method?

Can I get the name of the currently executing Meteor method (from within same)? This would be handy for logging.

I inspected this inside a Meteor method. It is an instance of MethodInvocation, and doesn't appear to have anything useful for figuring out the method name.

Seems like it would be easy enough to add the method name to MethodInvocation and callers, but I'm not sure if the maintainers would accept a patch that added a name field to every MethodInvocation instance.

Crossposted here.

Upvotes: 4

Views: 663

Answers (4)

HaveAGuess
HaveAGuess

Reputation: 1241

It's easy with Meteor 1.10.1

You can just use

this.name

e.g

new ValidatedMethod({
  name: "pod.create",
  validate: new SimpleSchema({
    stuff: {
      type: String,
    }
}).validator(),
  run(pData) {
    console.log("methodname:" + this.name);
  }
});

outputs :

I20210126-08:35:30.120(0)? methodname:pod.create

Upvotes: 1

JD2k
JD2k

Reputation: 48

Just my two cents, for a fully working monkey patched version (without underscore). Inside method function you can use this.currentMethodName now.

Meteor.methods = (object) => {
    let methods = {};
    let keys = Object.keys(object)
    keys.forEach(key => {
        methods[key] = function () {
            let self = this;
            let args = [...arguments];
            self.currentMethodName = key
            return object[key].apply(self, args);
        }
    })
    oldMeteorMethods(methods);
}

Upvotes: 0

avalanche1
avalanche1

Reputation: 3592

I've reworked a little bit @user337's answer. Now you can use @name inside method function.
Add this to server code (coffeescript):

currentMethod = new Meteor.EnvironmentVariable()
oldMeteorMethods = Meteor.methods

Meteor.methods = (object) ->
    methods = {}
    _.each object, (func, name) ->
        methods[name] = ->
            args = _.toArray(arguments)
            this.name = name
            currentMethod.withValue name, =>
                func.apply this, args
    oldMeteorMethods methods

Upvotes: 0

user3374348
user3374348

Reputation: 4101

It's not ideal, but here's how you could monkey-patch Meteor.methods to get this functionality, like stubailo suggests:

var currentMethod = new Meteor.EnvironmentVariable();    

function log(message) {
  var method = currentMethod.get();
  if (method) {
    console.log(method + ": " + message);
  } else {
    console.log(message);
  }
}

var oldMeteorMethods = Meteor.methods;

Meteor.methods = function (object) {
  var methods = {};
  _.each(object, function (func, name) {
    methods[name] = function () {
      var self = this;
      var args = _.toArray(arguments);
      return currentMethod.withValue(name, function() {
        return func.apply(self, args);
      });
    };
  });
  oldMeteorMethods(methods);
}

Meteor.methods({
  example: function (arg1, arg2) {
    log("hello");
    return doSomethingElse(arg1) + arg2;
  }
});

function doSomethingElse(x) {
  log("doSomethingElse called with " + x);
  return x * 2;
}

// Meteor.call("example", 5, 6) logs:
// "example: hello"
// "example: doSomethingElse called with 5"

If you prefer not to monkey-patch:

defineMethods = function (object) {
  var methods = {};
  _.each(object, function (func, name) {
    methods[name] = function () {
      var self = this;
      var args = _.toArray(arguments);
      return currentMethod.withValue(name, function() {
        return func.apply(self, args);
      });
    };
  });
  Meteor.methods(methods);
}

defineMethods({
  example: function (arg1, arg2) {
    log("hello");
    return doSomethingElse(arg1) + arg2;
  }
});

Upvotes: 4

Related Questions