Reputation: 789
comment.html:
<template name="comment">
<img src="{{photo}}"> //blank
{{photo}} //blank
</template>
comments.js:
Template.comment.helpers({
photo: function(){
Meteor.call('getPhoto', function(error, result) {console.log(result);return result})
}
});
server.js:
Meteor.methods({
getPhoto: function () {
return Meteor.user().services.vk.photo;
}
});
Problem: console.log returns right value, but {{photo}} is empty. Question: why 'photo' is empty?
Upvotes: 1
Views: 193
Reputation: 9767
I just realized what's the problem here.
Meteor.call
is calling an async function, like an ajax call. So Meteor.call('getPhoto')
would return undefined, the result is only retrievable in the callback
Meteor.call('getPhoto',function(err,result){console.log(result)});
With that in mind, you would need to come up with a way that captures that result in the callback. One solution is to use ReactiveVariable
:
You would first need to $ meteor add reactive-var
Template.comment.created = function (){
var $this = this;
$this.photo = new ReactiveVar("loading");
Meteor.call('getPhoto', function (err, result) {
if (err) console.log(err);
$this.photo.set(result);
});
}
And now define your helper to get the value;
//this is optional
Template.comment.helpers({
photo: function(){
return Template.instance().photo.get();
}
});
Another solution is to use Session
:
//everything here is in the client
Meteor.call('getPhoto', function(error, result){
Session.set('thePhoto', result);
});
// use reactive Session variable in helper
Template.comment.helpers({
photo: function(){
return Session.get('thePhoto');
}
});
The thing about using Session
is that you are setting a global variable and if you have many comments and every comment would need to have an unique photo, Session
is probably not the best way to do it.
You are calling the function Meteor.call
when you are declaring the helpers.
Template.comment.helpers({
photo: Meteor.call('getPhoto', function(error, result) {console.log(result);return result})
});
So what you are doing is equivalnt to:
var a = Meteor.call('getPhoto', function(error, result) {console.log(result);return result})
Template.comment.helpers({
photo: a //a is just a value
});
For .helpers
to work properly, you should be assigning a function to photo
instead.
Template.comment.helpers({
photo: function(){
var r;
Meteor.call('getPhoto', function(error, result) {r = result});
return r;
}
});
Under the hood, each helper starts a new Tracker.autorun. When its reactive dependencies change, the helper is rerun. Helpers depend on their data context, passed arguments and other reactive data sources accessed during execution. -From Meteor Doc
.helpers
is supposed to be invoked as the very reason why you want to use .helpers
is to enable reactivity in your view. Thus what's inside .helpers
need to be functions.
If you still don't get what I mean, here is simplified example:
var a = function(){ console.log("hey"); return 1}
var b = a();
var c = a;
b(); //this would run into an error saying that b is a not a function
c(); //this would console.log "hey"
Upvotes: 2