Note that there are some explanatory texts on larger screens.

plurals
  1. POMeteor - How can I pass data between helpers and events for a template?
    text
    copied!<p>I'm a bit new to Meteor and something I'm having trouble with is reactive data -- particularly in instances where I need to change the data shown based on a mouse or keyboard event. Doing this kind of stuff the normal js way seems to give me trouble in meteor since everything I change gets re-rendered and reset constantly.</p> <p>So, I thought I'd see if this would be a case in which I could use Meteor's Deps object, however I can't quite grasp it. Here's the code I'm using:</p> <pre><code>(function(){ var tenants = []; var selectedTenant = 0; var tenantsDep = new Deps.Dependency; Template.tenantsBlock.tenantsList = function() { tenants = []; var property = $properties.findOne({userId: Meteor.userId(), propertyId: Session.get('property')}); var tenancies = _Utils.resolveTenancies(property, true, null, true); for(var i = 0; i &lt; tenancies.length; i++) { if(tenancies[i].tenancyId == Session.get('tenancy')) { tenants = tenants.concat(tenancies[i].otherTenants, tenancies[i].primaryTenant); } } tenants[selectedTenant].selected = 'Selected'; tenantsDep.changed(); return tenants; }; Template.tenantsBlock.onlyOneTenant = function() { tenantsDep.depend(); return tenants.length &gt; 1 ? '' : 'OneChild'; }; Template.tenantsBlock.phoneNumber = function() { tenantsDep.depend(); for(var i = 0; i &lt; tenants[selectedTenant].details.length; i++) if(_Utils.getDynamicContactIconClass(tenants[selectedTenant].details[i].key) == 'Phone') return tenants[selectedTenant].details[i].value; return null; }; Template.tenantsBlock.emailAddress = function() { tenantsDep.depend(); for(var i = 0; i &lt; tenants[selectedTenant].details.length; i++) if(_Utils.getDynamicContactIconClass(tenants[selectedTenant].details[i].key) == 'Email') return tenants[selectedTenant].details[i].value; return null; }; Template.tenantsBlock.addedDate = function() { tenantsDep.depend(); return _Utils.timeToDateString(tenants[selectedTenant].created); }; Template.tenantsBlock.events({ 'click .Name': function(e, template) { tenantsDep.depend(); var _this = e.currentTarget; var tenantName = _this.innerHTML; $(_this).addClass('Selected'); $(_this).siblings().removeClass('Selected'); for(var i = 0; i &lt; tenants.length; i++) { if(tenants[i].name == tenantName) tenants[i].selected = "Selected"; else tenants[i].selected = ''; } } }) })(); </code></pre> <p>^This seemed to be what they were getting at in the meteor documentation (<a href="http://docs.meteor.com/#deps_dependency">http://docs.meteor.com/#deps_dependency</a>) for dependency.changed() and dependency.depend(), but all this does is give me an infinite loop.</p> <p><strong>So can I modify the way I declare deps to get this to make data reactive? Is there a better way to do this all together?</strong></p> <p>UPDATE:</p> <p>Although I was skeptical to do so, I've been inclined to try to use Session.set/Session.get in a localized way. So, the next time I have to do this, I'll just do </p> <pre><code>Session.set('tenantsBlock' {tenants: [], selectedTenant: 0}); </code></pre> <p>and then just access this variable from within helpers and event maps related to Template.tenantsBlock. That way they all have real time access to the data and they all get re-run when the data changes. Here's what I converted this script into (sorry these are both so large):</p> <pre><code>(function() { Template.tenantsBlock.created = Template.tenantsBlock.destroyed =function() { _Utils.setSession('tenantsBlock', { tenants: [], selectedTenant: 0 }) }; Template.tenantsBlock.tenantsList = function() { var localContext = Session.get('tenantsBlock'); localContext.tenants = []; var property = $properties.findOne({userId: Meteor.userId(), propertyId: Session.get('property')}); var tenancies = _Utils.resolveTenancies(property, true, null, true); for(var i = 0; i &lt; tenancies.length; i++) { if(tenancies[i].tenancyId == Session.get('tenancy')) { localContext.tenants = localContext.tenants.concat(tenancies[i].otherTenants, tenancies[i].primaryTenant); break; } } localContext.tenants[localContext.selectedTenant].selected = 'Selected'; Session.set('tenantsBlock', localContext); return localContext.tenants; }; Template.tenantsBlock.onlyOneTenant = function() { var localContext = Session.get('tenantsBlock'); return localContext.tenants.length &gt; 1 ? '' : 'OneChild'; }; Template.tenantsBlock.phoneNumber = function() { var localContext = Session.get('tenantsBlock'); for(var i = 0; i &lt; localContext.tenants[localContext.selectedTenant].details.length; i++) if(_Utils.getDynamicContactIconClass(localContext.tenants[localContext.selectedTenant].details[i].key) == 'Phone') return localContext.tenants[localContext.selectedTenant].details[i].value; return null; }; Template.tenantsBlock.emailAddress = function() { var localContext = Session.get('tenantsBlock'); var selectedTenantDetails = localContext.tenants[localContext.selectedTenant].details; for(var i = 0; i &lt; selectedTenantDetails.length; i++) if(_Utils.getDynamicContactIconClass(selectedTenantDetails[i].key) == 'Mail') return selectedTenantDetails[i].value; return null; }; Template.tenantsBlock.addedDate = function() { var localContext = Session.get('tenantsBlock'); return _Utils.timeToDateString(localContext.tenants[localContext.selectedTenant].created); }; Template.tenantsBlock.events({ 'click .Name': function(e, template) { var localContext = Session.get('tenantsBlock'); var _this = e.currentTarget; var tenantName = _this.innerHTML; for(var i = 0; i &lt; localContext.tenants.length; i++) { if(localContext.tenants[i].name == tenantName) { localContext.tenants[i].selected = 'Selected'; localContext.selectedTenant = i; } else { localContext.tenants[i].selected = ''; } } Session.set('tenantsBlock', localContext); } }) })(); </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload