Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Meteor Subscribe and Display Users Count

I'm trying to display the number of users in my footer and I would like this number in real time. I think the proper way is to create a publication in the server and to subscribe from the client.

// server/publications.js
Meteor.publish("usersCount", function () {
    return Meteor.users.find();
});

// client/main.js
UsersCount = new Meteor.Collection("usersCount");
Meteor.subscribe('usersCount', [], function() {
    console.log('subscribed.');
});

// client/views/layout/footer.js
Template.footer.helpers({
    famecoiners: function(){
        return UsersCount.find().count();
    }
});

// client/views/layout/footer.html
<span>{{famecoiners}} Famecoiners!</span>

In the chrome console, we can see the 'subscribed' string from the callback function. The problem is: {{famecoiners}} always returns 0 in my template.

like image 837
Julien Le Coupanec Avatar asked Dec 10 '13 18:12

Julien Le Coupanec


People also ask

What is Meteor subscribe?

If the client passed arguments to subscribe , the function is called with the same arguments. To publish records to clients, call Meteor. publish on the server with two parameters: the name of the record set, and a publish function that Meteor will call each time a client subscribes to the name.

How does meteor publishing work?

In Meteor a publication is a named API on the server that constructs a set of data to send to a client. A client initiates a subscription which connects to a publication, and receives that data.


1 Answers

Publishing all of the users will work, but it isn't practical. What if you have 10,000 users? What you really want to do is create a client side collection that holds only one item representing the count. If you look at the second example in the Publish and subscribe section of the docs, you'll see something that does this. I'll present a complete working example below:

$ meteor create test
$ cd test
$ rm test.*
$ mkdir server client
$ meteor remove autopublish
$ meteor add coffeescript

client/client.coffee

# Create a client-side subscription for the count of users.
UsersCount = new Meteor.Collection 'users-count'

Meteor.subscribe 'usersCount'

Meteor.startup ->
  Meteor.setInterval (->
    # To show something working, read the users count every second.
    uc = UsersCount.findOne()
    console.log uc.count or 0
  ), 1000

server/server.coffee

# Create a 'Users' group for this demo instead of using accounts-password.
Users = new Meteor.Collection 'users'

Meteor.publish 'usersCount', ->
  count = 0 # the count of all users
  initializing = true # true only when we first start
  handle = Users.find().observeChanges
    added: =>
      count++ # Increment the count when users are added.
      @changed 'users-count', 1, {count} unless initializing
    removed: =>
      count-- # Decrement the count when users are removed.
      @changed 'users-count', 1, {count}

  initializing = false

  # Call added now that we are done initializing. Use the id of 1 since
  # there is only ever one object in the collection.
  @added 'users-count', 1, {count}
  # Let the client know that the subscription is ready.
  @ready()

  # Stop the handle when the user disconnects or stops the subscription.
  # This is really important or you will get a memory leak.
  @onStop ->
    handle.stop()

Meteor.startup ->
  # To show something working, insert a new user ever 0.5 seconds.
  Meteor.setInterval (-> Users.insert {}), 500

Sorry if you don't like the CoffeeScript - I wanted the code to be compact.

$ meteor start

If you open the console you will see the user count increase. For fun you can open the mongo shell and run db.users.remove(); and watch it reset.

like image 51
David Weldon Avatar answered Oct 05 '22 05:10

David Weldon