0

I was trying to display a count of all online users on my website, and installed the meteor-user-status plugin to help with this. I thought all I had to do was add a template helper

Template.header.helpers({
    numOnline: Meteor.users.find({"status.online":true}).count()
});

like so, and include the {{numOnline}} variable in my header template. But, for some reason, that resulted in always displaying 0 users online. However, when I simply ran the method Meteor.users.find({"status.online":true}).count() in the javascript console, it gave the correct amount of users online.

After messing around with it a bit, I got it to work by wrapping it in a function:

Template.header.helpers({
    numOnline: function(){
        return Meteor.users.find({"status.online":true}).count();
    }
});

This change makes it work perfectly, but I have no clue why. Can someone explain why it was necessary to wrap it in a function?

arxenix
  • 180
  • 2
  • 12

2 Answers2

1

Adding Christian Fritz, The only reason I think this can be happening is in the first case numOnline: Meteor.users.find({"status.online":true}).count() the collection is not ready at the point of evaluation of the template and assign 0 or empty array [] since is what the subscription return, and in the second case since is a function will react whenever a change occurs in a collection, so that's why will have the value a soon the collection get fill with the subscription and the function will get execute whit the most recent value.Just my two cents. Please correct me if I'm wrong.

ncubica
  • 8,169
  • 9
  • 54
  • 72
  • This seems like a good explanation. Do you know why this works? Template.messages.helpers({ messages: Messages.find({}) }) , the messages automatically update even though Messages.find({}) isnt wrapped in a function – arxenix Jul 07 '15 at 05:10
  • Meteor automatically bind find() iterators, and react when any event happens on the collection. read this, `deps autorun` vs `collection observe` http://stackoverflow.com/questions/25999324/meteor-deps-autorun-vs-collection-observe and you will understand a little better :), [Deps happens automatically all the time in `meteor` without you notices] – ncubica Jul 07 '15 at 15:42
0

Well, that's just what it is (and the documentation tells you so, too). The reason why this need to be a function is reactivity: in order to reevaluate the piece of code at a later point in time (when a reactive datasource has changed value), you need to have a function.

Christian Fritz
  • 20,641
  • 3
  • 42
  • 71
  • Can you explain why stuff like this works then? Template.messages.helpers({ messages: Messages.find({}) }); I'm not wrapping Messages.find({}) in a function, but whenever a new message gets added, it automatically updates – arxenix Jul 07 '15 at 04:50
  • Interesting. I didn't know that that works, too. But it's hardly relevant. If you want to code outside of what is suggested by the meteor developers, you are doing so at your own risk as that sort of behavior may change in the future. [Looks like ncubica has a good explanation.] – Christian Fritz Jul 07 '15 at 16:24