how to return value on Meteor.call() in client?
Ex:
var data = Meteor.call('myMethod', functoin(error, result){
if(error){
alert('Error');
}else{
return result;
}
});
how to return value on Meteor.call() in client?
Ex:
var data = Meteor.call('myMethod', functoin(error, result){
if(error){
alert('Error');
}else{
return result;
}
});
The âresultâ wonât be in data.
This is regular async programming.
What do you want to do with your data ?
You can put it in a reactive variable for other parts of your app to use.
Meteor.call(âmyMethodâ, functoin(error, result){
if(error){
alert(âErrorâ);
}else{
Session.set(âdataâ, result)
}
});
A Meteor method is usually composed of 2 parts: a server-side part (letâs call it the server-side method) and a client-side part (letâs call it the stub).
If, from the client you want to get the result of the server-side method, use a callback like this:
Meteor.call('myMethod', arg1, arg2, function(error, result) {
// 'result' is the method return value
});
If, from the client you want to get the result of the stub, use this undocumented parameter of the apply function:
var result = Meteor.apply('myMethod', [arg1, arg2], { returnStubValue: true });
I strongly suggest against using this pattern. A stub is a stub and in no way represents the actual return value of the method thatâs going to be evaluated on the server. Seeking the result of a method call should be done within the callback.
Well, if you do definitely know absolutely for hundred percent sure that the client and server results are going to be the same, perhaps there is some case for it, but I still donât feel itâs right. But again, one may than argue why you need a method for whatever youâre doing within that method if it can execute on the client just the same.
very thanks for the clear solution.
If done correctly client-side methods / stubs can be useful for latency compensation.
if you can, please explainâŚ
[âŚ] perhaps there is some case for it
There is a common one:
Meteor.methods({
insertDoc: function(args) {
...
return MyCollection.insert(doc);
});
I think you should call the above method with returnStubValue: true
.
Sure you can achieve the same result by generating an _id
client-side (with the Random package) and pass it as a parameter to the method, but it looks overkill.
Notice also that Collection.insert
is a built-in Meteor method whose stub returns a value, and nobody is shocked. To me, MDG has been all wrong hiding stub return values. This introduces special cases and makes methods more difficult to understand.
I just donât agree with @serkandurusoy who âI strongly suggest against using this patternâ.
This is actually how meteor does latency compensationâŚ
Eg:
// Define the method on both client and server
Meteor.methods({
test: function() {
if (this.isSimulation) {
return 1; // Client wants this to be 1
} else {
return 2; // Server wants this to be 2
}
}
});
Template.hello.events({
'click button': function () {
// Call the test method sync
var clientResult = Meteor.apply('test', [], {returnStubValue: true},
function(err, serverResult) {
if (clientResult !== serverResult) { // 1 !== 2
// If client and server disagree let server correct the client
Session.set('result', serverResult); // -> 2
}
}
);
// Expect that the stub is correct
Session.set('result', clientResult); // -> 1
}
});
@raix, this is in my opinion a very good reason to not use returnStubValue
unless you know exactly what you are doing.
Per your example, the client - although for a brief moment - assumes a wrong result with which it can do unwanted things like display some secret information.
Granted, your example is a tamed one where you explicitly suggest you know what you are doing.
But @Steveâs first example suggests that the client should go on with the possibly wrong result and not care about what the server has to say.
And again @Steveâs second example assumes that (even if an id is generated on the client) the server will not throw an error, possibly due to some other criteria, like a unique key index!
Put in other terms, I think latency compensation is a great feature that Meteor has blessed us with, but it is something like the cross guards of that new light sabre from star wars 7. You can easily chop your own hands off if you donât know how to wield it.
And I do see that inexperienced meteor developers are a tad too trigger happy with latency compensation.
For a brief moment, yes. This is what latency compensation is about. I agree this requires to be extra careful.
Thanks for pointing me to Star Wars 7 new lightsabre, didnât know about it :- )
Yep, itâs that brief moment that concerns me where the code might be doing some nasty things with the uncertain result.
Also, I think it is permanent if you use returnStubValue: true
so that also requires extra attention. (Or please correct me if Iâm wrong)
Also, I just cannot resist the urge: https://www.youtube.com/watch?v=W2kHXf7mSD8
I think it is permanent if you use
returnStubValue: true
Nope, it just makes the stub result to be returned instead of being discarded.
The the doc here and the code here.
Hm, now Iâm confused.
Quoting parttially from @raixâs example:
Meteor.methods({
test: function() {
if (this.isSimulation) {
return 1; // Client wants this to be 1
} else {
return 2; // Server wants this to be 2
}
}
});
Template.hello.events({
'click button': function () {
// Call the test method sync
var clientResult = Meteor.apply('test', [], {returnStubValue: true});
Session.set('result', clientResult);
}
});
If you do not provide the callback, does clientResult
ever get overwritten by the server result?
If not - and thatâs what I believe how it works - Iâm correct to say that the result is permanent and you donât know what the server will respond with.
Otherwise, yes, it will not be permanent, but then again whatâs the point of a callback then?
It seems I didnât understand what you initially meant by âpermanentâ, sorry for that.
Yes, if you donât provide a callback, you have no way to know what the server will return.
To get back on track:
Collection.insert
relies on returnStubValue: true
. If you want to make a case against returnStubValue: true
, youâll have to explain whatâs wrong with Collection.insert
(which returns an _id
immediately, long before the server has actually inserted anything in the collection).
Taken from http://docs.meteor.com/#/full/insert
On the client, insert never blocks. If you do not provide a callback and the insert fails on the server, then Meteor will log a warning to the console. If you provide a callback, Meteor will call that function with error and result arguments.
Insert is a special method which randomly creates an id, returns that id immediately, and than continues on with inserting into minimongo, followed by the actual insert on the server. But again, it also does provide some feedback in the form of a warning on the client console.
I think this should be stressed on that part of the document that the client insert is not something that should be relied upon. As far as I see it, this is implied by the warning and I find that insufficient.
Also, the client insert is required to go through an allow/deny mechanism where the platform suggests that client inserts are not to be taken lightly, nor trustworthy.
I think if one decides to use latency compensation, I think it should be considered a feature as a progressive enhancement where it provides value in terms of improved UX where the journey of the client result ends right there and is non-critical.
Well done!
But not convincing enough to me :- )
Haha, well I do respect that
Now i find the package for this simple:reactive-method
and deanius:promise
.
I will try its.
Wow, I was planning to do same thing as deanius:promise
! Gonna try it!