Confused by Meteor Guide Method code

I was looking over the Meteor Guide and found this code for a method definition:

Meteor.methods({
  'Todos.methods.updateText'({ todoId, newText }) {
    new SimpleSchema({
      todoId: { type: String },
      newText: { type: String }
    }).validate({ todoId, newText });

    const todo = Todos.findOne(todoId);

    if (!todo.editableBy(this.userId)) {
      throw new Meteor.Error('Todos.methods.updateText.unauthorized',
        'Cannot edit todos in a private list that is not yours');
    }

    Todos.update(todoId, {
      $set: { text: newText }
    });
  }
});

I’m confused by a couple things here.

  1. How is this even a valid object: function declaration? Maybe this is some JavaScript trickery I’m unaware of, but this doesn’t appear to be valid code:
    'Todos.methods.updateText'({ todoId, newText })
    It looks kinda like a function declaration, but it isn’t. I’m tempted to say it’s just erroneous code, but I’ve been messing around with JS long enough to raise my eyebrow at things like this.

  2. Regardless of whether or not it turns out to be valid code, why subvert the Method pattern so badly? The pattern found in the docs looks somewhat different:

     Meteor.methods({
       foo: function (arg1, arg2) {
         check(arg1, String);
         check(arg2, [Number]);
    
         // .. do stuff ..
    
         if (/* you want to throw an error */) {
           throw new Meteor.Error("pants-not-found", "Can't find my pants");
         }
    
         return "some return value";
       },
    
       bar: function () {
         // .. do other stuff ..
         return "baz";
       }
     });
    

What advantage does structuring our code as given in the guide give as opposed to the example given in the Docs?

1 Like

This is an example of ES2015 enhanced object properties (method properties and property shorthand). So, we take:

foo: function({abc: abc, def: def}) {...}

and replace with:

foo({abc, def}) {...}

The intention with the use of simple-schema (I assume this is what you are referring to) is that the Meteor check method throws an error which only appears as a Meteor.Error(400, "Match Failed") on the client, whereas the validate() method of simple-schema gives a more informative error.

Yeah that looks incorrect syntax. Should have been:

Meteor.methods({
  ['Todos.methods.updateText']({ todoId, newText }) {
    // method body
  }
})

ES2015 allows dynamic/computed keys in object literals, if the expression is within square brackets like [<expression_that_evaluates_to_string>]. Applicable to method names too.

UPDATE: turns out [] is needed only for expressions that are not string literals (see @hwillson’s comment below and my reply to it). So the example is correct!

You don’t need square brackets with the function definition; try the following in Chrome’s console:

const testObject = { 
  'say.hello'() { 
    console.log('Hello!'); 
  } 
}; 
testObject['say.hello']();

1 Like

You’re right, I stand corrected! Didn’t realize it accepts string literals like that. So square brackets are a must only if the expression is not a string literal. Like:

let i = 0;
const testObject = { 
  [`method_${i}`]() { 
    console.log('Hello!'); 
  } 
}
1 Like

Actually in the examples I see they don’t include ’ ’ around Todos.methods.updateText .