Question

Using meteor js, I notice that if i have documents like this

{"q1":"someValue1","q2":"someValue2","q3":"someValue3","q4":"someValue4"}

quite often my helpers end up like this EDIT: I end up repeating the creation of helper-per-field a lot

Template.whatever.helpers({
gimmeResults1: function(){return myCollection.find({},{fields:{"q1":1}})},

gimmeResults2: function(){return myCollection.find({},{fields:{"q2":1}})}
});

with averaging one field in a really ugly way such as

q1Avg: function () {
  var count = myCollection.find({},{fields:{"q1":1}}).count();
  var total = 0;
  myCollection.find({},{fields:{"q1":1}}).map(function(doc) {
    total += doc.q1;
  });
  return avg = (Math.round((total / count)*100))/100;
}

(using a variable would still entail multiple db queries, correct?)

is there some design pattern I should be using to iterate over fields of a document and-autocreate template helpers?

what other ways can I eliminate spaghetti code?

Was it helpful?

Solution

The first step might look like this:

getField = function(collection, field) {
  var projection = {};
  projection[field] = 1;
  return collection.find({}, {fields: projection});
}
UI.registerHelper("getField", getField);

Which you would call in your templates like {{getField myCollection "q1"}}, together with a helper returning myCollection. You could take it further:

var makeFieldGetter = function(collection, field) {
  return function() {
    return getField(collection, field);
  };
};

Template.whatever.helpers({
  gimmeResults1: makeFieldGetter(myCollection, "q1")
  gimmeResults2: makeFieldGetter(myCollection, "q2")
});

Or even further:

var makeFieldGetters = function(collection, fields) {
  var obj = {};
  fields.forEach(function(field) {
    obj["gimme_" + field] = makeFieldGetter(collection, field);
  });
  return obj;
};

Template.whatever.helpers(makeFieldGetters(myCollection, ["q1", "q2"]));
// creates helpers gimme_q1, gimme_q2
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top