I'm a little new to Meteor, and I'm having problems with reactive data - especially when I need to change the data presented on the basis of the mouse or keyboard events. Doing this kind of thing in the usual js way seems to be causing me meteor problems because everything I change is constantly being updated and reset.
So, I thought I'd see if this would be the case when I can use the Meteor Deps object, but I cannot fully understand it. Here is the code I'm using:
(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 < 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 > 1 ? '' : 'OneChild'; }; Template.tenantsBlock.phoneNumber = function() { tenantsDep.depend(); for(var i = 0; i < 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 < 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 < tenants.length; i++) { if(tenants[i].name == tenantName) tenants[i].selected = "Selected"; else tenants[i].selected = ''; } } }) })();
^ It seems like this is what they got in the meteor documentation ( http://docs.meteor.com/#deps_dependency ) for dependency.changed () and dependency.depend (), but all this gives me an infinite loop.
Can I change the way deps are declared to make this data reactive? Is there a better way to do this all together?
UPDATE:
Although I was skeptical about this, I was inclined to try to use Session.set / Session.get in a localized way. So next time I do it, I just do
Session.set('tenantsBlock' {tenants: [], selectedTenant: 0});
and then just access this variable from the helpers and event cards associated with Template.tenantsBlock. Thus, everyone has access to data in real time, and they all start again when the data changes. Here I turned this script into (sorry, both of them are so big):
(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 < 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 > 1 ? '' : 'OneChild'; }; Template.tenantsBlock.phoneNumber = function() { var localContext = Session.get('tenantsBlock'); for(var i = 0; i < 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 < 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 < 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); } }) })();