Running client-side Meteor.method?

How can I call a client-side defined Meteor.method from the server?

I have a Meteor.method defined inside my client/ folder which calls a phone number using cordova plugin.

When I write Meteor.call(‘callNumber’, 0000000) from the serverside, the following error appears.

2015-08-12 10:19:44.697411544 +0200 CEST [web-1] [stderr] Error: Can't call yield in a noYieldsAllowed block!
2015-08-12 10:19:44.697424793 +0200 CEST [web-1] [stderr]     at Function.Fiber.yield (packages/meteor/fiber_helpers.js:8:1)
2015-08-12 10:19:44.697440167 +0200 CEST [web-1] [stderr]     at Function.wait (/app/node_modules/fibers/future.js:183:14)
2015-08-12 10:19:44.697452507 +0200 CEST [web-1] [stderr]     at Object.Future.wait (/app/node_modules/fibers/future.js:397:10)
2015-08-12 10:19:44.697467524 +0200 CEST [web-1] [stderr]     at [object Object]._.extend.runTask (packages/meteor/fiber_helpers.js:81:1)
2015-08-12 10:19:44.697504115 +0200 CEST [web-1] [stderr]     at [object Object]._.extend.addHandleAndSendInitialAdds (packages/mongo/observe_multiplex.js:47:1)
2015-08-12 10:19:44.697523799 +0200 CEST [web-1] [stderr]     at [object Object].MongoConnection._observeChanges (packages/mongo/mongo_driver.js:1179:1)
2015-08-12 10:19:44.697535641 +0200 CEST [web-1] [stderr]     at [object Object].Cursor.observeChanges (packages/mongo/mongo_driver.js:854:1)
2015-08-12 10:19:44.697550284 +0200 CEST [web-1] [stderr]     at Function.LocalCollection._observeFromObserveChanges (packages/minimongo/observe.js:177:1)
2015-08-12 10:19:44.697561969 +0200 CEST [web-1] [stderr]     at [object Object].Cursor.observe (packages/mongo/mongo_driver.js:848:1)
2015-08-12 10:19:44.697576044 +0200 CEST [web-1] [stderr]     at R (app/server/alert/alert.js:11:8)

I’m not sure about your error. However:

  • you cannot have a client-side-only method,
  • you can not call client code from server (I think the only server->client communication feature Meteor has is published collection).
1 Like

The documentation for Meteor.method and Meteor.call is a little ambiguous in that it states either may exist anywhere (i.e. on the client or the server) … which is true, but the usage is not interchangeable. Reading the docs in more detail leads to these:

From: http://docs.meteor.com/#/full/meteor_methods

Defines functions that can be invoked over the network by clients…
Calling methods on the server defines functions that can be called remotely by clients…
Calling methods on the client defines stub functions associated with server methods of the same name…
Stubs are run for their side-effects: they are intended to simulate the result of what the server’s method will do, but without waiting for the round trip delay…

and from: http://docs.meteor.com/#/full/meteor_call

This is how to invoke a method. It will run the method on the server. If a stub is available, it will also run the stub on the client…
Finally, if you are inside a stub on the client and call another method, the other method is not executed (no RPC is generated, nothing “real” happens)…

Long story short - you can’t call a client method (i.e. a stub) from the server. You can call a stub from a stub. You can call a server method from the client or the server.

@Steve: lol - you beat me to it!

2 Likes

I get it. I have read the docs but they were confusing indeed, because it stated Meteor.methods could be defined anywhere.

Thanks for the responses.

How would I do this? How can I call a block of code on the client from the server passing some arguments?

You can define collection and manipulate with document inside it.
And using Cursor’s observe function to react to these on client http://docs.meteor.com/#/full/observe

I would always be very cautious about exposing potentially exploitable code (in fact I wouldn’t do it) - and any code on the client is just that.

That’s actually how I’ve done it in the past. I thought there was a better option, but there seems not to be :wink: Maybe some packages provide a better solution…