Using Meteor, I'm attempting to understand when to use server-side Meteor.methods()
while still retaining instant UI updates.
From Andrew Scala's introductory tutorial, he claims that Meteor.methods()
should be used when you want to update and modify your database documents:
The idea is that you define all the functions on the server that do dangerous stuff like modify and update data, and then let the client call those functions and get return values like regular functions. The client never sees the implementation and doesn’t personally modify the data. The server does all the work.
And following this advice, I implemented this in my code:
Server-side:
Meteor.methods({
addMovie: function(data) {
var movie = Movies.insert({name: data});
return movie;
},
...
Client-side:
Template.movies.events = ({
'click #add-movie': function(e) {
var name = document.getElementById('movie-name').value;
Meteor.call('addMovie', name);
return false;
},
...
This works, but it's slow. The UI doesn't update instantly like it would if you called Movies.insert()
on the client-side. The docs indicate that, to rectify the problem, you can create stubs on the client-side:
Calling methods on the client defines stub functions associated with server methods of the same name. You don't have to define a stub for your method if you don't want to. In that case, method calls are just like remote procedure calls in other systems, and you'll have to wait for the results from the server.
But what should these stubs look like? Should it basically look the same as the server-side method? If so, what's the point? I'm looking for a more comprehensive explanation of the use and purpose of Meteor.methods()
, the point/use of stubs, and their implementation.
EDIT: David Greenspan has helped clarify the use of Meteor.methods() and stubs on meteor-talk.
here's another example.
say you're writing a bingo game and you click the button to call "house!".. in the click event you might call a Method, e.g.
this will invoke the server method:
if you are the first to call "house", the method will mark you as the winner.. however, let's pretend the method is extremely slow and your client app is waiting.. you're 99% sure the server will confirm you are the winner - you just want to update the user's screen without the wait.. in this case implement a client-side stub:
when the server result returns, if the data returned is different to what you set in the stub, it will correct it and refresh the screen accordingly.
If you define a method on a file shared by client/server like
/collections
wouldn't it be accessible to both and automatically stub?So:
/collections/houses.js
This will be available to both the client and server. If it doesn't pass, the server will automatically reject the client update/revert it.
In short :
Define some methods (Meteor.methods) in the files pushed to the sever that will do actual work on the server, define some methods (Meteor.methods) in the files pushed to the client to get an 'instant' behavior on the client (such as a loading indicator) until the server pushes the resulting changes back to the client
Here's David's original post :
As said Daniel you can define a method on a file which not in client or server directories and available on both sides. You can also use
isSimulation
boolean value to make additional checking. For example it may looks something like this:Thus code in the conditional branch will be executed on server only.