简体   繁体   中英

Meteor.call (Meteor.methods) seem to run on both client and server--causing issues

I execute Meteor.call from the client side to a Meteor.methods method and as I console.log things, they are logged in both the command prompt and the browser console.

The issue with this is that it actually seems to be executing on the client side--which does not have access to the proper entities. While I get no errors on the command prompt, here's what is shown on the client side:

Exception while simulating the effect of invoking 'createInvite' Meteor.makeErrorType.errorClass {error: "not-found", reason: "evaluator_invite__entity_not_found", details: undefined, message: "evaluator_invite__entity_not_found [not-found]", errorType: "Meteor.Error"…} Error: evaluator_invite__entity_not_found [not-found] at Meteor.methods.createInvite ( http://localhost:3000/lib/collections/invites.js?505cdea882e0f829d521280c2057403ec134b075:38:15 )

Is it actually running on the client side? Should this error be there?

Meteor methods are expected to run on both environments if defined globally, this allows for a nice feature which is called latency compensation.

The whole latency compensation concept is off topic but basically it means simulating client-side what the server would actually do like inserting documents in the database right-away to design fluid UX. You're essentially predicting server behavior before it's even happening to make your client experience ultra-responsive by eliminating network latency.

An example of this might be inserting a comment in the database immediately after the user submitted it. In this case the Meteor method calls getting executed on both the server and the client will share the same code.

Sometimes it makes absolutely no sense to provide a client-only simulation - or "stub" - when designing a method responsible for sending emails for example.

Some other times it makes sense to share some part of the code but you need to access environment specific objects : for example a method to insert comments might use Email.send on the server to notify an author a comment has been added on his post.

Meteor.methods({
  insertComment: function(comment){
    check(comment, [...]);
    if(! this.isSimulation){
      Email.send([...]);
    }
    return Comments.insert(comment);
  }
});

Ultimately, you have to structure your code differently depending on how your method is supposed to behave.

  • For server-only methods, define them under the server directory, with no client-side counterpart.

  • For shared methods that can share exactly the same code on both environments, just define them globally.

  • For shared methods that just slightly differ, you can use Meteor.isClient / Meteor.isServer or method only property isSimulation to check against the current environment and execute specific code accordingly.

  • For shared methods that share little to no code, I personally use a pattern where I define the Meteor method on both client and server environment and take care of shared behavior like checking arguments validity, then I call a function responsible for actually implementing the correct behavior.

lib/method.js

Meteor.method({
  method: function(args){
    check(args, [...]);
    //
    return implementation(args);
  }
});

The trick is to define the implementation separately on client and server, depending on the context, the correct function will get called.

client/method.js

implementation = function(args){
  // define your client simulation / stub
};

server/method.js

implementation = function(args){
  // define your server implementation
};

Read how to structure your app: http://docs.meteor.com/#/full/structuringyourapp

If you want your methods to be run only on the server, put files with methods into server folder.

If you want latency compensation you can use conditionals in your methods:

Meteor.methods({
  method1: function() {
    if (Meteor.isClient) {
      //Do client side stuff
    }

    if (Meteor.isServer) {
      //Do server side stuff
    }
  }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM