0

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 !

David Panart
  • 656
  • 6
  • 20

2 Answers2

0

I recommend finding the collection helpers package on Atmosphere. This will enable you to write currentUser.name in a template and it'll automatically return users name helper function returns.

There is no problem working like this. It doesn't matter if the function is called multiple times. It won't hurt your apps performance.

PHP and meteor sessions are different. A meteor session lasts for as long as browser window remains open or the page is refreshed. You are right that meteor sessions are not the way to go for your problem.

Eliezer Steinbock
  • 4,728
  • 5
  • 31
  • 43
  • Thanks you a lot for your help and explanations :) Then i'll have to work with a real mongodb, as my app is made to receive thousands of users, but I havn't think about it yet. – David Panart Apr 15 '15 at 14:23
  • This also isn't a problem. You only publish specific users to the client. In general it'll only be one user (the logged in user). The client mini mongodb will only have one user so you don't need to cache anything. You should never be sending thousands of items to any single page. – Eliezer Steinbock Apr 15 '15 at 14:35
  • Yes, but server side, I'll need to use and set a mongodb, no ? – David Panart Apr 15 '15 at 15:13
  • Yes. But there are no templates server side (unless you install special packages, but don't). I think you need to read some tutorials on Meteor. Discover meteor is a good book. The database exists on the client and the server. You publish minimal info to the client, not 1k users. The client takes this data and builds the page using the templates you've written and the documents that were published by the server. – Eliezer Steinbock Apr 15 '15 at 15:20
0

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.

Community
  • 1
  • 1
Carson Moore
  • 1,287
  • 1
  • 8
  • 9
  • Thanks you a lot ! :) Indeeds, it seems to be a better way to do, even if it's a slight improvement. I'll do like this ! – David Panart Apr 15 '15 at 14:26