I would like to convert this piece of code to ES-6. So the for loop in the first example I used needs to be a for of loop. What happens is in the second version that the percentage calculation works just as expected as i can see in the console but it doesn't show in the UI. The older, first method works fine. How come?
// This one works fine
displayPercentages: function(percentages) {
var fields =
document.querySelectorAll(DOMstrings.expensesPercLabel);
var nodeListForEach = function(list, callback) {
for(var i = 0; i < list.length ; i++) {
console.log(list[i], i)
callback(list[i], i)
}
};
nodeListForEach(fields, function(el, index){
if(percentages[index] > 0){
el.textContent = percentages[index] + '%'
}else{
el.textContent = '---';
}
});
},
// Second version has a problem showing percentages in the UI
displayPercentages: function(percentages) {
var fields = document.querySelectorAll(DOMstrings.expensesPercLabel);
var nodeListForEach = function(list, callback) {
for(let [el, index] of list.entries()) {
console.log(el, index)
callback(el, index)
}
};
nodeListForEach(fields, function(el, index){
if(percentages[index] > 0){
el.textContent = percentages[index] + '%'
}else{
el.textContent = '---';
}
});
},
Since your for
loop's body uses the index, you're probably best off sticking with a for
loop, not switching to for-of
.
You can switch to for-of
(on browsers that have implemented making NodeList
iterable, or if you polyfill it, or by using Array.from
) by spreading the NodeList
out into an array (or using Array.from
to create an array) and then using Array.prototype.entries
, which gives you an an iterator where each value iterated is an [index, value]
array:
displayPercentages: function(percentages) {
var fields = document.querySelectorAll(DOMstrings.expensesPercLabel);
for (const [index, el] of [...fields].entries()) {
if (percentages[index] > 0) {
el.textContent = percentages[index] + '%'
} else {
el.textContent = '---';
}
}
}
(Note that Array.prototype.entries
is fairly new and may need polyfilling.)
But: That's really quite indirect compared to just using a for
loop:
displayPercentages: function(percentages) {
var fields = document.querySelectorAll(DOMstrings.expensesPercLabel);
for (let index = 0; index < fields.length; ++index) {
const el = fields[index];
if (percentages[index] > 0) {
el.textContent = percentages[index] + '%'
} else {
el.textContent = '---';
}
}
}
...or for that matter, using the forEach
that is on NodeList
now (which, again, you can polyfill):
displayPercentages: function(percentages) {
document.querySelectorAll(DOMstrings.expensesPercLabel).forEach((el, index) => {
if (percentages[index] > 0) {
el.textContent = percentages[index] + '%'
} else {
el.textContent = '---';
}
});
}