add the result of a meteor call to the current data context reactively

- 1 answer

Ad

Here is the situation. I have a list of games that I am subscribing to and showing to the user. i.e. {_id: '325jfsd3253', gameName: 'shoot2', earnedAchievements: 20} and each game has a list of achievements within another collection i.e. {_id: '324545fe23', gameId: '325jfsd3253', achievementName: 'savior'. I am trying to get the total achievement count without having to subscribe to every achievement record for each game. I am doing this by doing a Meteor.call() to the server within each game template gameTemplate.onCreated function that returns the total achievement count for each game. Currently, I am trying to use a reactive var to set the value that is returned from the meteor call like so.

Template.gameTemplate.onCreated = function() { 
    //the reactive var is set beforehand. this.data._id is the game id
    Meteor.call('getGameCount', this.data._id, function(error, result)   {
        if (error) return;
        reactiveVarForCount = result;
    }
}

and then using the reactive var in a helper like so

remainingAchievements: function () {
    //the earnedAchievements of the game is within the parent context
    var parentData = Template.parentData(1);
    var totalAchievements = totalAchievementDependency.get();
    if (parentData && totalAchievements) {
        return totalAchievements - parentData.earnedAchievements;
    }
    //return 100;
}

however, the reactive var is reset for each game and so only ends up holding the value of the result of the last game to get counted (the last time the meteor method getGameCount is called). What would be the best way to attach the result of a meteor method call to the current data context and have it be reactive so that the UI updates when the new data is returned and the helper is re-run.

Ad

Answer

Ad

I actually answered this myself. By placing the reactive var within the onCreated callback and attaching it to the template instance, I was able to scope it correctly and have one reactive var for each instance of the template.

Template.myGame.onCreated = function() {
   var self = this;
   var self.achiCount = new ReactiveVar();
   Meteor.call('getGameCount', self.data._id, function(err, res) {
       if (err) return;
       self.achiCount.set(res);
  });
}

and then you can access the reactive var through the template instance like so:

Template.myGame.helpers({
   getCount: function() {
      //this will be the reactive var value and will be reactive
      return Template.instance().achiCount.get();
   }
});
Ad
source: stackoverflow.com
Ad