. . . (hopefully) useful stuff for web development and life

How to publish to a client-only collection in Meteor

In Meteor, a client-only collection is a database that is kept only on client side, without being synced with server (as a normal collection would be). Because the collection is not automatically synced, we will need to manually ‘push’ changes from server to client every time we want to publish something new.

For better illustration, let’s say we want to write a simple (and silly) app that retrieve and display current server’s time.

We start by defining a client-only collection:

1

2

3

4

5

/******* Client Code *********************************************/

varServerTime=newMeteor.Collection('serverTime');

/*****************************************************************/

Next, we define a helper publication on server:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

/******* Server Code *********************************************/

// This will be used to store the subscription objects for later management

varsubs={};

// The helper publication

Meteor.publish('helperPublication',function(){

// #1

varsubscription=this;

subs[subscription._session.id]=subscription;

// #2

subscription.added('serverTime','a_random_id',{date:newDate()});

// #3

subscription.onStop(function(){

delete subs[subscription._session.id];

});

});

/*****************************************************************/

The general idea is we will have each client subscribe to a helper publication. This helper publication will help us create and maintain a set of subscription objects that represent the current clients connected to the server. Then later we can ‘push’ changes from server to clients via those subscription objects. In more details:

Step #1: Every time a client connects, the publish() method will be run. The ‘this’ inside the method represents a client subscribing to the publication. We save ‘this’ to an object named ‘subs’ for later management.

Step #2: We use the added() method to signal the client: “Hey, let’s create a new document in your client-only ‘serverTime’ collection, give it an _id of ‘a_random_id’, and then store this Date object in it”. The result: Right after subscribing to the helper function, each client will have a initial value of server time.

Step #3: We want to make sure that we will not waste time with disconnected clients, so when a client disconnects we remove it from ‘subs’.

Next, on server, we setup an interval that runs every 1 second. Each time the interval function is executed, we tell each of the subscription in subs: “Hey, remember the document with _id ‘a_random_id’ I sent you before? Now it should be changed. Please update it with this new Date object”.

1

2

3

4

5

6

7

8

9

10

11

/******* Server Code *********************************************/

Meteor.setInterval(function(){

varcurrentTime=newDate();

for(varsubscriptionID insubs){

varsubscription=subs[subscriptionID];

subscription.changed('serverTime','a_random_id',{date:currentTime});

}

},1000);

/*****************************************************************/

Finally, in client code, we have each client subscribe to the above-mention helper function:

1

2

3

4

5

/******* Client Code *********************************************/

Meteor.subscribe('helperPublication');

/*****************************************************************/

All connected clients will receive continuous update of server time, every second.

ABOUT THE AUTHOR

Phuc Nguyen

I'm a web developer, a big fan of the Meteor framework, and a former startup founder. Currently I'm looking for an interesting and challenging Meteor project to join. You can read more about me at phucnguyen.info.

It looks like I manage to make it works. But it became very foggy when ‘this._session.id’ comes.

Can you explain me what does ‘this’ refer to? My guess is ‘Meteor’ itself.

Where did you find this _session.id property and what does it refer to? Again, my guess is DDP but I find nothing about _session in Meteor’s doc. I found it in Meteor’s code source but — wow! — I did not understand.

Finally (it is related), is there a simple way to get rid of the ‘sub’ object. I don’t need it as only one user will work on the dataset?