Populating an HTML list using array.map()

Mastering both .map() and DOM manipulation is an invaluable skill

Despite how powerful and prevalent modern libraries and frameworks are these days, they are merely abstractions on top of vanilla JavaScript. To understand the effects and benefits of the abstractions (e.g., React JSX, React components, etc.), it is helpful to understand how it works in vanilla JavaScript.

Manually inputting content is absolutely terrible

In continuing the refresh of my understanding of CSS and HTML, I started working on yet another FCC "guided project". This one has the student build what FCC calls a "magazine" (though really it just emulates a single albeit robust blog post.)

One of the steps has the student manually input content (!!) into li elements in a list. The content of each li is contained in h4 and p child elements. In the context of this project, the list serves as a high-level history of FCC.

Note that there are six (6) li elements.

Side note: At this stage of a person first learning HTML and CSS, JavaScript is not a concern, so they wouldn't be expected to know how to use JavaScript to do this.

<!-- Relevant excerpt of the student built FCC "Magazine" project -->
<article class="brief-history">
  <h3 class="list-title">A Brief History</h3>
  <p>Of the Curriculum</p>
  <ul class="lists">
  <!--Below this comment is where the course hs the student manually 
    fill out each li, including the child elements, and their 
    contents -->
    <li> <!-- List item 1 -->
      <h4 class="list-subtitle">V1 - 2014</h4>
      <p>We launched freeCodeCamp with a simple list of 15 resources, including Harvard's CS50 and Stanford's Database Class.</p>
    </li>
    <li> <!-- List item 2 -->
      <h4 class="list-subtitle">V2 - 2015</h4>
      <p>We added interactive algorithm challenges.</p>
    </li>
    <li> <!-- List item 3 -->
      <h4 class="list-subtitle">V3 - 2015</h4>
      <p>We added our own HTML+CSS challenges (before we'd been relying on General Assembly's Dash course for these).</p>
    </li>
    <li> <!-- List item 4 -->
      <h4 class="list-subtitle">V4 - 2016</h4>
      <p>
        We expanded the curriculum to 3 certifications, including Front End, Back End, and Data Visualization. They each had 10 required
        projects, but only the Front End section had its own challenges. For the other certs, we were still using external resources like
        Node School.
      </p>
    </li>
    <li> <!-- List item 5 -->
      <h4 class="list-subtitle">V5 - 2017</h4>
      <p>We added the back end and data visualization challenges.</p>
    </li>
    <li> <!-- List item 6 -->
      <h4 class="list-subtitle">V6 - 2018</h4>
      <p>We launched 6 new certifications to replace our old ones. This was the biggest curriculum improvement to date.</p>
    </li>
  </ul>
</article>

JavaScript to the rescue

Something you might notice is a certain "signature" of each li element. The "signature" is basically the following HTML.

<li class="list-subtitle">
  <h4></h4>
  <p></p>
</li>

In React, this might very well be a component powered by JSX. In vanilla JavaScript, it will just be added to the DOM as a template literal. In both cases, the effect to the end user is that there will be six of these in the DOM.

In vanilla JavaScript (and in React) we can eliminate this tedium by traversing an array of arrays. There are other ways to do this--like using an array of objects--but for now we will just use an array of arrays.

Define your array of arrays

We will first want to define our array. It is this array of items that will be traversed to programmatically add content to the DOM.

Each item in the array will be an array. Each subarray will have two items, with the first representing the h4 content, and the second representing the p content.

// Array of arrays
const history = [
  ["V1 - 2014", "We launched freeCodeCamp with a simple list of 15 resources, including Harvard's CS50 and Stanford's Database Class."], // Subarray 1
  ["V2 - 2015", "We added interactive algorithm challenges."], // Subarray 2
  ["V3 - 2015", "We added our own HTML+CSS challenges (before we'd been relying on General Assembly's Dash course for these)."], // Subarray 3
  [
    "V4 - 2016",
    "We expanded the curriculum to 3 certifications, including Front End, Back End, and Data Visualization. They each had 10 required projects, but only the Front End section had its own challenges. For the other certs, we were still using external resources like Node School.", // Subarray 4
  ],
  ["V5 - 2017", "We added the back end and data visualization challenges."] // Sub array 5
  ["V6 - 2018", "We launched 6 new certifications to replace our old ones. This was the biggest curriculum improvement to date."] // Subarray 6
];

We will next need to write the code that powers the traversal of the history array.

Select your list element and apply .map() to history array

The below code will select the list element in the DOM (in this case, the ul--the only one on the page).

It will also apply the .map() function to the history array, such that each item in history will be added to the page programmatically.

// Code to translate the 'history' array into the DOM
const ul = document.querySelector("ul");

history.map((item) => {
  const [h4, p] = item; // Array destructuring
  ul.insertAdjacentHTML(
    "beforeend",
    `<li class="list-subtitle">
        <h4>${h4}</h4>
        <p>${p}</p>
    </li>`
  );
});

Key takeaways

Simply put, it is annoyingly tedious to copy-paste the li "signature" and manually input the content inside the h4 and the p in every item. Sure, an array with six items is manageable enough without the need for .map(), but just imagine if you had an array of 50 items!

This is merely a basic example of the power of JavaScript (or rather of programming in general).

Check out the CodePen to see it in action!