How to return value on Meteor.call() in client?

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.

2 Likes

Well done!
But not convincing enough to me :- )

Haha, well I do respect that :smile:

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!

I have attempted to use a callback to get the return value of result but it keeps coming back undefined. No errors are occurring, so I can’t figure out why it’s not returning. Thoughts as to why?

And how you are returning it ?
Cause you cant use it directly as return value from helper.

I have the following

// on server
Meteor.methods({
  myMethod: function (arg1, arg2) {
    var result = getResult(arg1, arg2);
    return result;
  },
});

// on client
Meteor.call('myMethod', arg1, arg2, function(error, result) {
  if (error) {
    // handle error
  }
  else {
    console.log(result);
  }
});
2 Likes

and when u log it on server side before returning ?

Never mind. I figured out the issue. I’m using aldeed:simple-schema insert, which has callbacks for insert and update for validation purposes. I was returning it in the callback which obviously won’t work.

Regardless, i too would like to know how we are generally supposed to access the value returned by the Meteor.method we Meteor.call

my client:
`Template.admin.helpers({

isAdmin: function(){ 
    var result = Meteor.call('checkIfAdmin', function(error, result){return result;});
    console.log(result);
    return result; 
}

});`

and my server method
`Meteor.methods({

checkIfAdmin: function() {
    var isAdmin = Meteor.user().isAdmin;
    console.log(isAdmin);
    return isAdmin;
}

});`

where my Meteor.users has a callback hook for
Accounts.onCreateUser( function(options, user){ user.isAdmin = false; return user; });

for example…

i’ll report back when I find out, as we need to clarify this, as the docs show a … in the function body and it’s not precisely clear how the result is to be accessed on the client…console.log on the server is fine. on the client it’s undefined…

it appears i’m not the only one who thinks things are unclear…

So I tried a Meteor.apply with returnStubValue:true or something like this… because it’s an async call it still doesn’t have a value for the template helper… so i finally just put the method call out of the helper and used the session to store my returned method value…

Meteor.apply('checkIfAdmin', [],  function(error, result){ 
    if(result) Session.set('userIsAdmin', result); return; } );

Template.admin.helpers({
        isAdmin: function(){ 
        return Session.get('userIsAdmin'); 
    }
});

please excuse the Meteor.apply instead of Meteor.call… same same

All is well exceptyou mispelled function

Just to be clear the disputed topic here is in @Steve’s second suggested method, getting the result of the stub? But the first method, using ‘result’ in the callback is fine right?

callback is the way to go on the client

1 Like

or use this maybe?

I am having issues now with error handling and success messages, so maybe I have to use async await?