Change subscription on the click of a button

In my application, people can add multiple accounts in their ‘dashboard’. For example, there are 3 accounts connected with different usernames. I have a collection called userData where all of the data for all 3 accounts is stores with a field username that contains the unique username of the corresponding account.

In the main page, I’m displaying the users as such and the account holder can choose whose data they want to see:

<template name="accountSelector">
   {{#each account}}
      <a href="/user/{{this.username}}>{{this.username}}</a>
   {{/each}}

   {{#if userSelected}}
      {{userSelected.information}}
   {{/if}}
</template>

What would be the best way to do this? I don’t mind if the data can’t be displayed on the same page since that’s how it’s set up currently. I tried using routes without much luck…this is what I did with the routes:

Router.route('/user/:someParameter', {
  template: 'accountSelector',
  data: function(){
    var current = this.params.someParameter;
    return PostSubs.subscribe('userData', current );
  }
});

But this didn’t work out too well. I would have to refresh the page to get the template to react to the subscription change. For example, if I was looking at the user Adam's information and clicked on Betty, it would show Adam's data until I the page was refreshed and then Betty's information would come up.

You could remove the data object in the router, and move to a template level subscription. You need to place the subscription in an autorun function, and get the param or current user data reactively.

Template.accountSelector.onCreated(function() {
  this.autorun(c => {
    const currentUser = 'sampleParam' //// get the param you need reactively in some way  FlowRouter.getParam('user') etc
    if (currentUser) {
      this.userSub = this.subscribe('userData', this.userParam)
      this.user = currentUser
    }
  }
}

Template.accountSelector.helpers({
  userSub () {
    const inst = Template.instance()
    return inst.userSub && inst.userSub.ready() // you can monitor this and place loading animation etc, 
    // or re-initialize the select if needed, depending on the component's api
  }

})

Tempate.accountSelector.events({
  'change .user-dropdown': function(event, template) {
    // update param or set template.instance() var etc anything reactive, that the autorun monitors
  }
})

1 Like

Thanks! This helped me a lot. I was using Tracker.autorun before without the arrow notation, so the reference to this was being lost. I tried this.autorun with the arrows and it worked!

So, the solution above worked fine. In the template accountSelector , I have a graph template called infoGraph. When the accountSelector template is created, the subscription works are intended but the graph doesn’t render anymore because it apparently isn’t getting the data subscription.

If the template accountSelector renders while I’m on a different tab, all of the data, including the graph loads fine but if I’m on the actual application page, it doesn’t seem to load the graphs. For the template infoGraph, I have a Tracker.autorun function in the onRendered to retrieve the data from the collection when available but it doesn’t seem to work anymore.

Any suggestions?

The graph rendering problem was solved by surrounding graph template handlebars {{> infoGraph}} with {{#if userSub}}

1 Like