-1

I want to generate HTML code with two functions as a training exercise. The first function creates an individual list item. The second function takes an array with the actual items as input and creates the list, like so:

Function 1:

const listItem = item => `<li class="list-item">${item}</li>`;

Function 2:

const unorderedList = items => `<ul class="list">\n ${items.forEach((item) => { listItem(item); })}\n </ul>`;

The result should be something like this:

<ul class="list">
  <li class="list-item">car</li>
  <li class="list-item">bike</li>
  <li class="list-item">train</li>
</ul>

However my code returns

<ul class="list">
 undefined
</ul>

Can someone explain to me what I'm doing wrong?

  • 6
    `forEach` doesn’t return anything. – Mark Jul 28 '19 at 07:13
  • Thanks @MarkMeyer. Is there a way to have forEach return something? How would I use a ```forEach``` loop here instead of the solution with ```map``` below? – newkidontheblock Jul 28 '19 at 07:26
  • @MarkMeyer even if you return the value (removing the brackets) its still `undefined` – Abdelillah Aissani Jul 28 '19 at 07:27
  • Hi @astarisborn please check some basic of js https://stackoverflow.com/questions/34426458/javascript-difference-between-foreach-and-map – Rishab Jul 28 '19 at 07:29
  • @astarisborn you can't use `forEach` this way inside a template because it won't ever return anything. The `map` solution is a good one. You can also use `reduce()`. – Mark Jul 28 '19 at 07:32
  • @Dadboz — the brackets aren't the issue. `forEach` returns `undefined` regardless of what you do inside the callback. – Mark Jul 28 '19 at 07:33
  • Thank you @MarkMeyer for the clarification and Rishab for the link – newkidontheblock Jul 28 '19 at 07:49

1 Answers1

3

You need to use .map to transform each item into a listItem result, and then join:

const listItem = item => `<li class="list-item">${item}</li>`;
const unorderedList = items => `<ul class="list">\n
  ${items.map(listItem).join('')}\n
  </ul>`;

console.log(
  unorderedList(['car', 'bike', 'train'])
);

If you want newlines between each <li>, then join by newlines instead of the empty string (though it won't affect the rendered <ul>):

const listItem = item => `<li class="list-item">${item}</li>`;
const unorderedList = items => `<ul class="list">\n
  ${items.map(listItem).join('\n')}\n
  </ul>`;

console.log(
  unorderedList(['car', 'bike', 'train'])
);
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320