Reputation: 1232
I've got a whole bunch of data being passed to a view in a Node App, and a bunch of it relates to budgets, specifically quote vs. actual.
The variables are all named similarly, like this
s_budget_quote_labour = 500
s_budget_actual_labour = 400
s_budget_quote_food = 1000
s_budget_actual_food= 1100
I want to create a custom array in my Pug template, that consists of all the cost "types" and then iterate over them, piping the cost type into the variable name. Basically something like this:
- expenseArray = ['Food', 'Labor']
- each expense, i in expenseArray
- var expense_budget = 'info.s_budget_' + expense
- var expense_actual = 'info.s_actual_' + expense
tr
td ${expense}
td ${expense_budget}
td ${expense_actual}
The idea being that it will loop over all of the items in my array, and pull together the proper html to build my table of expenses. I've tried piping it directly into the td a couple different ways too, but no luck. Samples...
td #{info.s_actual_${expense}}
td !{info.s_actual_${expense}}
And a few other variants... all without luck. Any idea if this is possible and how to do it?
Upvotes: 1
Views: 399
Reputation: 30408
eval
should let you get variables with dynamic names. And you can use .toLowerCase
to make the case match:
- expenseArray = ['Food', 'Labor']
- each expense, i in expenseArray
- var expense_budget = eval('info.s_budget_' + expense.toLowerCase())
- var expense_actual = eval('info.s_actual_' + expense.toLowerCase())
tr
td ${expense}
td ${expense_budget}
td ${expense_actual}
However, eval
could cause security problems if users can specify the value of expenseArray
. Those users could cause arbitrary JavaScript to be run for anyone who visits that page. This solution would also need more code if you needed it to support spaces or special characters in the names of expense types. So I don't recommend this.
Instead, you should change the format of the info
variable that is sent to your view. Make it so an object or Map
is sent instead of multiple variables with a special naming scheme. For example, info
could be this:
var info = {
'Labour': {quote: 500, actual: 400},
'Food': {quote: 1000, actual: 1100},
}
And then your template would be this:
- expenseArray = ['Food', 'Labor']
- each expense, i in expenseArray
- var expense_budget = info[expense].quote
- var expense_actual = info[expense].actual
tr
td ${expense}
td ${expense_budget}
td ${expense_actual}
Upvotes: 0