Search code examples
javascriptmongodbmeteor

Make Meteor Reactive to Specific Subitem of Meteor.user()


What I'm Trying to Do...

I need to use some subproperties which are stored in the user's Meteor.user() object, such as Meteor.user().profile.preferences.preference_one, Meteor.user().profile.preferences.preference_two, et cetera. These subproperties are being used inside reactive autorun blocks because there are recalculations that must be done anytime they change.

My Problem Is...

I've discovered that when I refer to the value of these subproperties from within a reactive block, then the autorun is fired for any change to the Meteor.user() object, including changes which do not affect in any way the data that I am explicitly referencing. For example, if Meteor.user().profile.name is updated, then any autorun that includes Meteor.user().profile.preferences.preference_one or Meteor.user().profile.preferences.preference_two gets fired as well, because they all have a common parent.

I have seen a similar question dealing with limiting the scope of Meteor's reactivity, but it deals with a custom collection, not the Meteor.users collection. I cannot see how the solution there could be made applicable because they are specifying fields in subscriptions to limit what subproperties are published to the client, and in my case, I need all the subproperties of Meteor.user(). But I need to be able to choose which subproperties I am reacting to!

Storing subproperty values locally and then comparing on every change would of course work, but it is a brute force solution solution in that it requires extra logic and that the autoruns will all be firing anyway.


Solution

  • I don't know if this is the best way, but have a look at this example:

    Tracker.autorun(function() {
      var user = Meteor.user();
      if (user && user.profile)
        Session.set('p1', user.profile.preference1);
    });
    
    Tracker.autorun(function() {
      var p1 = Session.get('p1');
      console.log("p1 is " + p1);
    });
    

    The first autorun will fire every time the user data changes, however the second autorun will fire only when that particular property changes.