Search code examples
javascriptmeteorminimongo

How to improve data handling with meteor


Still on my meteor app, i'd like to now how to improve my data handling from minimongo.

Used to SQL / PHP, I'd like to know how to find() an object from my minimongo collection only one time, and access each of its properties with helpers, without having to re-access the collection each time.

Until now, what I did was something like that :

Template.profile.helpers({
  name: function(e, tmpl){
    return Meteor.users.FindOne({_id: Meteor.userId()}.profile.name;
  },
  phone: function(e, tmpl){
    return Meteor.users.FindOne({_id: Meteor.userId()}.profile.phone;
  }

[...] });

But it's getting boring and i guess there must be a more efficient way to deal with it, something where I could load my entire users information only one time, and then display with a helper taking one parameter, to display the data like that : {{data name}}, {{data phone}}

With only one helper like that :

Template.profile.helpers({
  data: function(aString){
    if (aString == "phone)
      return [...].phone;
    }
  }
[...]
});

Of course, I can use a session value, but I'm not sure it's as relevant as I could do.

Another thing : how to end a Meteor session ? Because with PHP, the session ends at the closure of the browser, and cookies stay for a given duration, but with meteor session, i never have to reconnect as day after day, my logs seems to stay.

Would someone guide me through this or give me some good habits / tips ? I'm still reading the doc, but it's quite huge :S

Thanks you !


Solution

  • One thing to note here -- you're not actually sending a request to the server when you call Mongo.Collection.find() on the client -- that's getting handled by the miniMongo instance on the client, so it's not really that inefficient. Also, in this particular instance, the current user is always available as Meteor.user() -- no need to use Meteor.users.find({_id: Meteor.userId()}); (see docs for more info)

    However, if you really wanted to cache that value, you could do something like this:

    // JS
    var data; // scoped so it's available to the whole file
    
    Template.profile.onCreated({
        data = Meteor.users.findOne({_id: Meteor.userId()}); // above scope makes this new definition available to the whole file
    });
    

    Then, to do what you're describing with the string arguments, you can do something like...

    Template.profile.helpers({
        data: function(aString) { 
          if (data) { return data[aString]; }
        }
    });
    

    Perhaps a better option even is to send the Template a data context -- something like this in your HTML file:

    {{> profile currentUser}} <!-- currentUser returns Meteor.user() -->
    

    Which is directly available to your helpers as this:

    Template.profile.helpers({
      data: function(aString) { 
        return this[aString];
      }
    });
    

    You can also pass data contexts through IronRouter if you're using that for your routing.

    As for the Meteor session, the model is different than the model for PHP. In PHP, you store session information on the server, and every time you access the server, the browser (or client, more generally) sends along the session ID so it can look up anything pertaining to your session (see this question for a potentially better explanation). Meteor keeps track of clients that are connected to it, so the session will stay open as long as your browser is open. If you need to manipulate Meteor user sessions, take a look at this question.