Meteor async client pattern / how to implement waitOn for subscription list w callbacks

for various reasons, I'm writing an application that doesn't use IronRouter, but needs to implement some similar logic. One expects the subscription list to be ready.

Since this is an asynchronous client-side call to Meteor, what are the methods for this?

If I want to have a list of subtypes like:

  sublist = [
    PubSubMan.subscribe("Players"),
    PubSubMan.subscribe("Stuff")
  ]

      

then start with the rest of the app when they are all .ready() = true

what's a good way to do it?

I cannot figure out how the wait () method is implemented in the IR source code

This seems like a perfect case for a situation like aysnc.js where I want to name a list of methods and continue when their callbacks are done, but resorting to node style templates seems a little awkward for meteor. I've looked at wrapAsync and meteorhacks async utils , but it looks mostly like NPM server and package packaging methods.

If I could summarize a list of ready () values ​​and then create Tracker impressions that will fire if / when that sum changes ...? but not really sure how to do it.

Since each of the subscriptions fires a callback when I'm done, I think I could use a counter to keep track of when calling the callbacks, and keep a counter to check the length of the array length, but again this looks inelegant.

EDIT: This is not a perfect solution, but below works. But I still think I am missing a more elegant method.

  subList = [
    PubSubMan.subscribe("Players"),
    PubSubMan.subscribe("Stuff" )
  ]

  Tracker.autorun (c) =>
    subReady = _.filter subList, (item) ->
      return item.ready()
    allDone = (subList.length == subReady.length)
    console.log("subs status: #{subReady.length} / #{subList.length} = ready: #{allDone}")
    if allDone
      c.stop()
      startMainLoop()

      

related to this question about how tracker.autorun fetches its calculated dependencies how does Tracker.autorun choose its calculations?

0


source to share


1 answer


I'm not sure what yours is startMainLoop

, but here is an approach that might work for you. Create a new template that just checks if all subscriptions are ready; if they are the real main template, and if not, then it displays the download template.

<template name="subscriptionsReadyCheck">
  {{#if allSubsAreReady}}
    {{> mainTemplate}}
  {{else}}
    {{> loadingTemplate}}
  {{/if}}
</template>

      

subList = [...]

Template.subscriptionsReadyCheck.helpers {
  allSubsAreReady: -> _.every(subList, (sub) -> sub.ready())
}

      



Subscriptions are supposed to be created when the page is loaded and stays around until the page is closed. If you need subscriptions that are only created when the template is rendered and stop when the template is destroyed, you can save them in a template instance:

Template.subscriptionsReadyCheck.created = ->
  @subList = [...]

Template.subscriptionReadyCheck.destroyed ->
  for sub in @subList
    sub.stop()

Template.subscriptionsReadyCheck.helpers {
  allSubsAreReady: -> _.every(Template.instance().subList, (sub) -> sub.ready())
}

      

0


source







All Articles