Twit and other Node libraries don't always quite drop into Meteor's reactive architecture right out of the box. Luckily Meteor makes adapting them super-duper easy with wrapAsync. It was so easy that I naturally tried all the more difficult ways first! Since I didn't find a nice gist or StackOverflow example, please enjoy this one.
In the template -
{{#with pos}}
{{#if ready}}
{{> singlePosition data }}
{{/if}}
{{/with}}
In client.js -
Template.home.helpers({
pos: function () {
var ready = Meteor.subscribe('positions').ready();
apos = Positions.findOne({}, {sort: {'submittedOn': -1}});
if (apos && !apos.targetImg) {
console.log('calling targetImg for ' + apos.target);
var targetImg = Meteor.call("getTwitImg", apos.target, function(error, results) {
if (results)
Positions.update(apos._id, {$set: {'targetImg': results}});
});
}
return {
data: apos,
ready: ready
};
},
})
In server.js -
var T = new TwitMaker({
consumer_key: '...'
, consumer_secret: '...'
, access_token: '...'
, access_token_secret: '...'
})
var wrapGet = Meteor.wrapAsync(T.get, T);
Meteor.methods({
getTwitImg: function(target) {
data = wrapGet('users/show', {screen_name: target});
if (data) {
img_url = data['profile_image_url'];
US.update({twitter: target}, {$set: {'targetImg': img_url}});
return img_url;
}
}
});
Way easier than manually using bindEnvironment or Futures!