I have the following JavaScript that I'd like to translate to CoffeeScript:
function initPage() {
var tr = document.getElementsByTagName('tr')[0];
labs.forEach(function(lab) {
var td = document.createElement('td');
// Create a header for each lab.
var h2 = document.createElement('h2');
h2.innerHTML = lab.name;
td.appendChild(h2);
// Create a div for each machine in a given lab.
for(i = lab.first; i <= lab.last; i++) {
var machine = ((i < 10) ? "0" : "") + i;
var div = document.createElement('div');
div.setAttribute('id', lab.name + "-" + machine);
div.setAttribute('class', 'Grey');
div.innerHTML = machine;
td.appendChild(div);
}
// Append the new table data element to the table row.
tr.appendChild(td);
});
}
Right now my CoffeeScript translation looks something like this:
initPage = () ->
tr = document.getElementsByTagName('tr')[0]
labs.forEach (lab) ->
td = document.createElement 'td'
# Create a header for each lab.
h2 = document.createElement 'h2'
h2.innerHTML = lab.name
tr.appendChild h2
# Create a div for a machine given the machine number
createDiv = (i) ->
machine = if i < 10 then "0#{i}" else "#{i}"
div = document.createElement 'div'
div.setAttribute 'id', "#{lab.name}-#{machine}"
div.setAttribute 'class', 'Grey'
div.innerHTML = machine
td.appendChild div
# Create a div for each machine in a given lab
createDiv machine for machine in [lab.first..lab.last]
# Append the new table data element to the table row.
tr.appendChild td
Is there a better, more idiomatic way to create the divs for each lab? Would it be better to avoid the createDiv function and do something like:
for i in [lab.first..lab.last]
machine = if i < 10 then "0#{i}" else "#{i}"
div = document.createElement 'div'
div.setAttribute 'id', "#{lab.name}-#{machine}"
div.setAttribute 'class', 'Grey'
div.innerHTML = machine
td.appendChild div
The CoffeeScript language reference says
Most of the loops you'll write in CoffeeScript will be comprehensions over arrays, objects, and ranges.
and
Comprehensions should be able to handle most places where you otherwise would use a loop, each/forEach, map, or select/filter
I'm new to the idea of list comprehensions and want to make sure that I'm translating this code in a way that leverages the strengths of CoffeeScript appropriately.
Would it be better to avoid the createDiv function and just inline it?
Yes, that function looks a bit superfluous.
I'm new to the idea of list comprehensions and want to make sure that I'm translating this code in an appropriate way
The aim of list comprehensions is to build new lists, like map
and filter
would do it. And for which loops or (inappropriately) forEach
was used often, manually push
ing to an array.
However, your aim is not to create an array, but a DOM element only. Comprehensions don't help here, you will need to use them as loops to execute side effects.