javascriptmeteormeteor-publications

using publications to create a progressbar for subscriptions


I am calling a Google Analytics API multiple times and load that data into a subscription. Now I want to create a progressbar to inform the user that data is being loaded and give a view on how long it is going to take.

I read that it's best to use publications to pass data from server to client. Is this true?

I created following publication on the server. What is does is following:

  1. set the initial progressValue and the initial publication with id 1
  2. keep looping if the progressValue is less than 100 and tell that the publication of 1 is changing.
  3. Below this code I have an other publication running where progressValue is being set in steps in a loop.

When looking at the client only the last progressValue gets posted. Before this I receive a lot of empty arrays. So it's like:

[]
[]
[]
[]
...
Progress publication 

What I want is that the client receives every change in progressValue instead of only the last one. How can I solve this?

If there are any better suggestions on how to create a subscription progressbar, these answers will also be accepted.

if (Meteor.isServer) {
  let progressValue = 0;

  Meteor.publish('progress', function() {
    const self = this;
    let lastProgressValue = 0;

    const id = 1;

    self.added('progress', id, {
      progress: progressValue,
      total: 100,
    });


    while (progressValue < 100) {
      self.changed('progress', id, {
        progress: progressValue,
        total: 100,
      });
  }
 self.ready();      
  });
...

Solution

  • Hmm... so, a couple of things here.

    I read that it's best to use publications to pass data from server to client. Is this true?

    This is the whole point of Meteor, using ddp. Means that data is sent to the client automagically from the server. So, the bulk of the work to manipulate data is actually handled client side using minimongo.

    Have a look at this article for a good discussion of the 'automagic' part...

    http://richsilv.github.io/meteor/meteor-low-level-publications/

    How do you do progress?

    You don't want to try handle the incrementing on the server side. Instead, you want to get a simple count of the server, perhaps using a reactive aggregate (see my answer here How to reactively aggregate mongodb in meteor) and send that to the client. So, server does a count as a publication and tells the client '57' coming.

    Then as your normal data publication, you send the 57 records to the client. ON THE CLIENT, you now basically do the same sum as you did on the server, but as only some of the 57 data records have been received by the client, you effectively get a progress counter by dividing client received by the servers message of total to be sent.

    Summary

    On the SERVER - 2 publications, 1 reactive aggregate for the count of the records to be sent and 1 as the normal data being sent

    On the CLIENT - function to count the records in the local minimongo collection - collection.find({}).count() - will do the trick. This will increment as each record is received by the client from the server.

    Progress is as simple as count on client divided by server sent count to be delivered.