Joe C
Joe C

Reputation: 1855

How to DRY up Template Helpers in meteor?

My Template helper has duplicated code:

Template.foodMenu.helpers({
  breakfast: function() {
    var breakfastItems = EatingTimes.find(// query for breakfast items);
    // function to sort breakfastItems in here (code duplication)
  },
  lunch: function() {
    var lunchItems = EatingTimes.find(// query for lunch items);
    // function to sort lunchItems in here (code duplication)
  },
  dinner: function() {
    var dinnerItems = EatingTimes.find(// query for dinner items);
    // function to sort breakfastItems in here (code duplication)
  }
);

I would like to DRY it up:

Template.foodMenu.helpers({
  breakfast: function() {
    var breakfastItems = EatingTimes.find(// query for breakfast items);
    sortFoodItems(breakfastItems);
  },
  lunch: function() {
    var lunchItems = EatingTimes.find(// query for lunch items);
    sortFoodItems(lunchItems);
  },
  dinner: function() {
    var dinnerItems = EatingTimes.find(// query for dinner items);
    sortFoodItems(dinnerItems);
  }
);

Where do I place this function so I can DRY up? How do I name space it so I can call it properly? I am using Iron Router if that makes a difference.

var sortFoodItems = function (foodItems) { 
  // code to sort out and return foodItems to particular method that calls it   
};

Upvotes: 1

Views: 172

Answers (2)

Serkan Durusoy
Serkan Durusoy

Reputation: 5472

You could also create a global helper for this using Template.registerHelper(name, function) which would look like:

Template.registerHelper('menuItems', function(eatingTime, sortCriteria) {
  //do some checking of your arguments
  eatingTime = eatingTime || '/* your default eating time */';
  sortCriteria = sortCriteria || {/* your default sort criteria */};
  check(eatingTime, String);
  check(sortCriteria, Object);

  //find and sort your items in one mongo query or you could do separate find and sort if you want
  menuItems = EatingTimes.find({time: eatingTime}, sortCriteria);

  return menuItems; 
});

This would be the most meteoric way of DRYing up your code.

and then in your template, you could call it as:

{{#each menuItems 'time args' 'sort arg'}}

Upvotes: 1

Tomas Hromnik
Tomas Hromnik

Reputation: 2200

Just define you function before helpers in the same file

var sortFoodItems = function (foodItems) { 
  // code to sort out and return foodItems to particular method that calls it   
};

Template.foodMenu.helpers({
  breakfast: function() {
    var breakfastItems = EatingTimes.find(/* query for breakfast items */);
    sortFoodItems(breakfastItems);
  },
  lunch: function() {
    var lunchItems = EatingTimes.find(/* query for lunch items */);
    sortFoodItems(lunchItems);
  },
  dinner: function() {
    var dinnerItems = EatingTimes.find(/* query for dinner items */);
    sortFoodItems(dinnerItems);
  }
});

If you want to use sortFoodItems function in multiple files, create folder with name lib and put the function in file functions.js without var keyword to make it global. For example:

//lib/functions.js
sortFoodItems = function (foodItems) { 
  // code to sort out and return foodItems to particular method that calls it   
};

You need to understand how Meteor reads your project directories. Read more about structuring your application in Meteor docs.

Upvotes: 1

Related Questions