stiang
stiang

Reputation: 255

Meteor - Trouble using return value from Meteor.call

I’m probably showing my javascript ignorance here, but why doesn’t this work? And how can I do rewrite this piece of code to make it work?

// On the client
Template.tabs.title = function () {
  var msg;
  Meteor.call('getMessage', this.msg_id, function (error, result) {
    console.log(result); // Prints out a perfectly fine message object
    msg = result;
  });
  if (msg)
    return msg.title;
  else
    return "(empty)"; // This is always the value that's shown on the page
};

My understanding of the problem is that the "if" statement gets executed before the callback can set the msg variable. Is that right? Or is it a scoping problem? Can I even do it like this, calling "call" from the template?

The reason I’m using methods here it that the Messages collection can potentially be huge, and I can’t subscribe to it as a whole on the client. I have subscriptions for parts of it, but I also need to look up arbitrary messages, no matter what my subscriptions have available.

Upvotes: 2

Views: 1360

Answers (2)

Tom Coleman
Tom Coleman

Reputation: 3037

You are right about the callback not being set yet when you examine msg. I guess the best thing to do is just set a Session var when the callback returns and rely on Meteor's reactivity to redraw your message when that happens. Something like:

Template.tabs.title = function () {
  var title = Session.get('currentTitle');

  if (title) {
    return 'title';
  else {
    Meteor.call('getMessage', this.msg_id, function (error, msg) {
      Session.set('currentTitle', msg ? msg.title : "(empty)");
    });
  }
};

On the other hand I'd probably say using a single-message subscription to grab the 'current message' would make more sense and be more idiomatic.

Upvotes: 3

Alcides Queiroz
Alcides Queiroz

Reputation: 9576

The third parameter passed for the "call" method is an asyncronous callback, when you try to return your "msg" variable, it's not defined yet.

Use another callback, like this:

Template.tabs.retrieveTitle(callback){
  Meteor.call('getMessage', this.msg_id, function (error, result) {
   callback( (result) ? result.title : "(empty)" );
  });
}

And you could use the above method this way:

Template.tabs.retrieveTitle(function(){
//do what you want to
});

Upvotes: 1

Related Questions