1

I'm trying to loop a object using reduce to generate a html list

const dropdownTemplate = (data) => {
 console.log(data);  // always empty
 return `
  <li class="dropdown__item" data-value="${data.value}"><span class="dropdown__itemCode">${data.code}</span> <span class="dropdown__itemText">${data.name}</span></li>
 `;
};

const data_obj = JSON.parse('[ { "type": "hotel", "value": 25, "name":"Hotel name", "code": "sn", "lat" : "1.3", "long" : "1.33" } ]');
const fetched_items = data_obj.reduce((item, generated) => {
 generated += dropdownTemplate(item);
 return generated;
}, '');
console.log(fetched_items); // allways filled with undefined values

But can't understand why the item is always empty (so it generates the list with undefined values),

What am I doing wrong?

Toni Michel Caubet
  • 19,333
  • 56
  • 202
  • 378

2 Answers2

5

I think you inverted item and generated.

generated is the element keeped from one loop to another; and item the element of the array treated in the actual loop.

const dataObj = JSON.parse('[ { "value": 25, "name":"Hotel name", "code": "sn"  }, { "value": 30, "name2":"Hotel name2", "code": "sn2" } ]');

const dropdownTemplate = data => `<li class="dropdown__item" data-value="${data.value}"><span class="dropdown__itemCode">${data.code}</span> <span class="dropdown__itemText">${data.name}</span></li>\n\n`;

const fetchedItems = dataObj.reduce((tmp, x) => `${tmp}${dropdownTemplate(x)}`, '');

console.log(fetchedItems);
Orelsanpls
  • 22,456
  • 6
  • 42
  • 69
  • 1
    There's also no need to store back to the parameter, just: `return generated + dropdownTemplate(item);`. We can also use the concise form: `const fetched_items = data_obj.reduce((generated, item) => generated + dropdownTemplate(item), '');` – T.J. Crowder Jun 13 '18 at 15:51
  • @T.J.Crowder Right, I didn't even though about refactoring it ^^' – Orelsanpls Jun 13 '18 at 15:56
  • 1
    Ha! You went a step further with a template literal! :-) – T.J. Crowder Jun 13 '18 at 15:59
-2

Ideally you should use map for this kind of scenarios.

Reduce params are like this (aggregate, item) => {}

const dropdownTemplate = (data) => {
return `
    <li class="dropdown__item" data-value="${data.value}">
    <span class="dropdown__itemCode">${data.code}</span> <span class="dropdown__itemText">${data.name}</span>
    </li>`;
 };

const data_obj = JSON.parse('[ { "type": "hotel", "value": 25, "name":"Hotel 
name", "code": "sn", "lat" : "1.3", "long" : "1.33" } ]');

const fetched_items = data_obj.reduce((combinedHtml, item) => {
   combinedHtml += dropdownTemplate(item);
   return combinedHtml;
}, '');

console.log(fetched_items);
Mohit Verma
  • 1,620
  • 2
  • 20
  • 30