kadirahq / mantra

Mantra - An Application Architecture for Meteor
https://kadirahq.github.io/mantra/
978 stars 52 forks source link

How to handle multiple calls to same subscription? #163

Open hyperh opened 8 years ago

hyperh commented 8 years ago

I have container A and B in my app.

In A, a subscription is called to get the team for the app. However, B also requires the same team. Containers A and B are mounted on the same page. Given that I'm not sure on which order they load in, should I subscribe again in B, or should I just retrieve the team in B assuming that A already subscribed?

// Container A
export const composer = ({context}, onData) => {
  const {Meteor, LocalState, Collections, FlowRouter} = context();

  const teamId = FlowRouter.getParam('teamId');
  if (teamId) {
    if (Meteor.subscribe('teams.single', {teamId}).ready()) {
      const team = Collections.Teams.findOne(teamId);

      onData(null, {
        team
      });
    }
  }

What should Container B look like?

// Container B
export const composer = ({context}, onData) => {
  const {Meteor, LocalState, Collections, FlowRouter} = context();

  const teamId = FlowRouter.getParam('teamId');
  if (teamId) {
    if (Meteor.subscribe('teams.single', {teamId}).ready()) {
      const team = Collections.Teams.findOne(teamId);
      onData(null, {team});
    }
  }

// or...
export const composer = ({context}, onData) => {
  const {Meteor, LocalState, Collections, FlowRouter} = context();

  const teamId = FlowRouter.getParam('teamId');
  const team = Collections.Teams.findOne(teamId);
  onData(null, {team});
 }
fermuch commented 8 years ago

You should always subscribe. No container should know of a app-global scope unless it is part of the context.

The idea is: all the container needs to know is the context and what props it gets to render the component.

hyperh commented 8 years ago

@fermuch Are there any performance issues with subscribing twice to the exact same subscription?

I'm wondering if I should just subscribe once in the parent of A and B, then pass the team down through props? Is it more performant than subscribing twice?

But I always thought containers were supposed to remove the hassle of passing props down many levels of components that don't even use the props.

fermuch commented 8 years ago

No, there are none. When you subscribe, you're creating an object that Meteor stores locally saying "I am subscribed to XXX with the parameters YYY". Before subscribing again, meteor checks that. If there's already a subscription, you'll reuse that subscription instead of creating a new one. That way, you don't have to really care about subscriptions.

The only problem would be doing something like Meteor.subscribe('foobar', new Date), since that way you'll create new subscriptions all the time, since new Date will yield a new value each time, thus, creating a different parameter for each subscription, and making all things go slow.

fermuch commented 8 years ago

If you want to read some more about Meteor's pub/sub, here is a great answer with lots of examples.

payner35 commented 8 years ago

I think your subscriptions will reset if you Route to a new page / view.

so if you have multiple components (containers) on the same Route.. then you have no problem with multiple subs with the same values. But you should still think about how you best break down your components.. and make them as dumb as possible.

but if you call a new route.. the subs get called again.. This is where some sort of subscription caching can help.. such as "meteorhacks:subs-manager"