× {{alert.msg}} Never ask again
Get notified about new tutorials RECEIVE NEW TUTORIALS

MeteorJs + Sessions? you are doing it wrong

Ethan
Jan 26, 2016
<p>Its pretty common to use Sessions on Meteor, i mean they are on the Tutorial, but you should know that the more the project grows and get complex, the sessions will start changing from your friend to enemy.</p> <p><strong>So whats the solutions?</strong> you may ask.</p> <p>And the answer is <a href="https://atmospherejs.com/meteor/reactive-var">ReactiveVar</a>, and dont worry they keep the exact same flavor of the sessions with .set() and get().</p> <p> </p> <p>This is a common scneario of a Session.</p> <pre><code class="language-javascript">Template.myexample.events({ 'click .some' : function(event, template){ Session.set('postClicked', this._id) } }); Template.myexample.helpers({ showPostClicked : function(){ return Posts.findOne(Session.get('postClicked')); } }); Template.myexample.onCreated(function(){ var tmpl = this; Session.setDefault('postClicked', null); });</code></pre> <p> </p> <p>A few thing to take in care here.</p> <ol> <li>If you project grow up so fast, there is a hight chance to overwritte the state of a session in another onRendered, Method, Event, whathever.</li> <li>This could be to verbose, and this can relay in alot of Session.get() and Session.set().</li> </ol> <p> </p> <p>You should also know that the state of a session dosnt change on hot pushed, this means if you let meteor refresh your app, the value of the session will stay and thats it, thats the only sncearion when a Session will perserve, so if you are usings sessions because you came from a languaje like PHP and you think they will perseve on users refresh, thats not gonna happend.</p> <p> </p> <p><strong>ReactiveVar</strong> Example</p> <p> </p> <pre><code class="language-javascript">Template.myexample.events({ 'click .some' : function(event, template){ template.set('postClicked', this._id) } }); Template.myexample.helpers({ showPostClicked : function(){ return Posts.findOne(Template.instance(),postClicked.get()); } }); Template.myexample.onCreated(function(){ var tmpl = this; tmpl.postClicked = new ReactiveVar(null); });</code></pre> <p> </p> <p>Like you can see now the state of the session just belongs to the template instance itself, so you can have whathever times you want postClicked ReactiveVar and it will dosnt matter (dont do it).</p> <p>Problems:</p> <ol> <li>But Ethan... we are writting more code and its kinda the same thing?? isnt...</li> <li>how if i want to access that state of the variable inside a nested template?</li> </ol> <p> </p> <p>The answer of the first problem, its true the code get more bigger, but it could be fixed, in two ways.</p> <pre><code class="language-javascript">//You can writte the helper like this. Template.myexample.helpers({ showPostClicked : function(postId){ return Posts.findOne(postId); } }); {{#withPostClicked Template.instance().postClicked.get()}} {{! show post data }} {{/with}} //Template.instance is still to much verbose. //So lets register a global helper for it Template.registerHelper('instance', function() { return Template.instance(); }); //and now use it like {{#withPostClicked instance.postClicked.get()}} {{! show post data }} {{/with}} </code></pre> <p> </p> <p>And the answer of the second question, lets ilustrate that posible scneario.</p> <pre><code class="language-javascript">//Using the same example. {{#withPostClicked instance.postClicked.get()}} {{! show post data }} {{&gt; _postLike}} {{! not that we are calling an extra template over here}} {{/with}} </code></pre> <p> </p> <p>So lets say you want to give a like on this post, and have a good old component for that.</p> <p>But then when the user clicks on like like button you want to affect some state of a session that belong to the parent template.</p> <pre><code class="language-javascript">//Blaze to the rescue. Template._postLike.events({ 'click .postLike: function(event, template){ var parentTemplate = Blaze.getView('Template.parentTemplate') &amp;&amp; Blaze.getView('Template.parentTemplate').templateInstance(); parentTemplate.postClicked.set(null); } });</code></pre> <p> </p> <p>Easy huh? check<a href="http://docs.meteor.com/#/full/blaze_getview"> Blaze.getView</a>.</p> <p> </p> <p>There you got there are no more excuses to still using Session on your MeteorJs Apps.</p>
comments powered by Disqus