Search code examples
mongodbmeteormongodb-querymeteor-accounts

Meteor: Preferred method to selectively expose app-wide collection metadata to client? (i.e. for dashboard)


I'd like to implement an admin dashboard in my Meteor app, displaying data like user count, currently logged-in users, and metadata (counts, plots, etc.) from other collections.

Since my existing publications only expose each user's own "stuff" on the client side, and the users publication only exposes the logged-in user for security, I figure I'm going to need some new interfaces.

What would be the best way to collect and expose this data to the client conditionally, if a user with admin rights is logged-in? I'm thinking either a group of methods to provide each displayed parameter, or a dashboard method that collects all the parameters and returns them as a big JSON object... Is there a preferred way?


Solution

  • Any of your proposed solutions would work; I think it depends on the performance characteristics of each, which is probably something you would need to explore on your own.

    Offhand, it seems like if you return these in a reactive monolithic JSON object, depending how you structure it you might have to re-run the whole calculation each time something changes, which would probably be inefficient. Keeping the methods separate seems like it would be better, since you'd only be re-running calculations on changed data.

    You might check out the simple:reactive-method package or Discover Meteor pattern for using a Meteor method in a template helper to make that a bit easier. The pattern I would suggest would be something like:

    // lib JS
    Meteor.methods({
      userCount: function() { 
        var user = Meteor.user();
        if (user && user.admin) { 
          return Meteor.users.find().count();
        }
      }
    });
    
    // Client JS
    Template.dashboard.helpers({
      userCount: function() { 
        return ReactiveMethod.call('userCount');
      },
      isAdmin: function() { return Meteor.user().admin; }
    });
    
    // HTML 
    <template name='dashboard'>
      {{#if isAdmin}}
         There are {{userCount}} users.
         ... <!-- any other stuff you want -->
      {{/if}}
    </template>