How to override run() in ValidatedMethod?

Hi guys,

My situation is as follows. I have a package called ‘posts’ that implements a simple ‘posts-system’. Inside this package I defined a method called ‘Posts.methods.insert’ to insert new posts into the DB using the ValidatedMethod object. (https://atmospherejs.com/mdg/validated-method)

Posts.methods.insert = new ValidatedMethod({

name: ‘Posts.methods.insert’,

validate: new SimpleSchema({
matchId: {type: String},
text: {type: String}
}).validator(),

run({matchId, text}) {

  ///////////////
  // VARIABLES //
  ///////////////

  var context = 'Posts.methods.insert';
  var curUserId = Meteor.userId();
  var unexpError = {status: 'error', text: 'Unexpected_Error'};
  var postId = '';

  /////////////////////
  // CHECK ARGUMENTS //
  /////////////////////


  if (!curUserId) {
     throwError(context, 'the user is not logged in');
     return unexpError; // msg
  }
   // Post content
   text = text.trim();
   if (text.length === 0 || text.length > 2000) {
       throwError(context, 'text length = 0 or > 2000');
       return;
   }

  ///////////////////
  // DB-OPERATIONS //
  ///////////////////

  postId = Posts.collection.insert({createdBy: curUserId, postedOn: matchId, text: text});

   return postId;

}
});

Now, I want to import this package into my main application and override the Posts.methods.insert in order to add additional ‘checks’ before the insertion, and also additional operations after the insert (for instance, send notifications every time a new posts is inserted). So, the question is: how can override the ‘run’ function inside my Posts.methods.insert?

Thanks in advance!

In case someone had the same question, here is @sashko 's reply:

I think someone could add hook functionality with a mixin. Basically, you would add .before and .after functions to the Method, and wrap the run function to call those hooks if they have been added.

On the other hand, why not just put the stuff you are talking about
inside the method body itself? It seems like your app just won’t work
without the extra hooks, so what’s the reason to separate those from the
method?

And my reply to sashko’s question:

Concerning your question, I agree that putting all the logic within
the package’s method will work, but it seems to me that if I make a
package which is absolutely independent from my core-app, I will be able
to share it on atmosphere, and it can be used out of the box: simply
meteor-add the package and then call the template wherever you want to
use it. Then, it’s up to you to add the logic related to your specific
needs to handle additional checks and after operations. In the other way
round, if someone wants to use my package (s)he will have to clone the
repo and then change the insert method within the package. Additionally,
it would be necessary to ‘export’ some of the app-core logic/data so
that it’s available on the package.

This is my first time trying to build an app in a 'package-oriented’
way, so probably I’m wrong with my approach! But it seems to me that
using before and after hooks is much more modular and natural :slight_smile:

Would you prefer to have the conversation here or there? :stuck_out_tongue:

Haha, sorry, here it’s ok. I just wanted to post your reply here for completion :smiley:

Anyway, I guess there’s a line between “modular” and “action at a distance”. The question I’d ask myself is - could someone reasonably modify the method without worrying about the hooks, or modify the hooks without worrying about the method, and also can someone call the method without having to read both to understand what is going on?

For example, your hook could handle permissions and the method could handle the actual insert, and that could be fine. But if there is critical functionality split into a hook, I feel like that would just be hard to follow for other developers working on your app.

Yes, I agree that the approach I’m trying to use cannot/shouldn’t be used in all cases, there are parts of every app that are intrinsically related with each other so probably the hooks-approach wont work in those cases. But maybe for some functionality it could work nicely. After I finish refactoring my app I’ll have a clearer view about this topic :slight_smile: Thanks again for your time sashko and for all the work you are doing!

Of course, if someone else wants to share your experience, I’m always glad to learn!

Cheers

No problem. Will repeat it again: if someone wants to build and maintain a hook mixin for ValidatedMethod, I’ll be glad to help out!