Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template literal loop in javascript

I am trying to build an html table out of a JSON file. When i make my table with template literals in javascript, it loops through my whole table and makes a table header for each array in my json.

I have tried to make two functions for my th and my td but that doesn't seem to work.

var petsData = [{
    name: "Purrsloud",
    species: "Cat",
    favFoods: ["wet food", "dry food", "<strong>any</strong> food"],
    birthYear: 2016,
    photo: "https://learnwebcode.github.io/json-example/images/cat-2.jpg"
  },
  {
    name: "Barksalot",
    species: "Dog",
    birthYear: 2008,
    photo: "https://learnwebcode.github.io/json-example/images/dog-1.jpg"
  },
  {
    name: "Meowsalot",
    species: "Cat",
    favFoods: ["tuna", "catnip", "celery"],
    birthYear: 2012,
    photo: "https://learnwebcode.github.io/json-example/images/cat-1.jpg"
  }
];


function foods(foods) {
  return `
<h4>Favorite Foods</h4>
<ul class="foods-list">
${foods.map(food => `<li>${food}</li>`).join("")}
</ul>
`;
}

function petTemplate(pet) {
  return `
    <table>
      <tr>
        <th>Name</th>
        <th>Species</th>
        <th>Birth Year</th>
        <th>Favorite Foods</th>
      </tr>
        <td>${pet.name}</td>
        <td>${pet.species }</td>
        <td>${pet.birthYear}</td>
        <td>${pet.favFoods ? foods(pet.favFoods) : ""}</td>
      <tr>
      </tr>
    </table>
  `;
}

document.getElementById("table").innerHTML = `
  ${petsData.map(petTemplate).join("")}
`;
<div id="table"></div>

It just seems like my petTable function is looping again and again until i get all of the arrays in the json file, but that makes a table header for each for each array of json. I just want one table header and then all of the arrays.

like image 259
Louis Avatar asked May 03 '19 19:05

Louis


People also ask

What is a template literal in JavaScript?

Template literals are literals delimited with backtick (`) characters, allowing for multi-line strings, for string interpolation with embedded expressions, and for special constructs called tagged templates.

Can you put a for loop in a template literal?

Note that although I did say that you can't write loops in a template literal, that's only true for the for loop syntax. You can, however, call functions that loop as a part of an expression, and if that function returns a value, it'll be injected into the string.


1 Answers

"but that doesn't seem to work" is a bit vague, but of course if you keep the header cells in the same place as your rows, they will show up above each row. You can simply put your opening and closing markup into variables and ouput those before and after actually looping over the data with the row-generating function.

There's also an error in your original markup, with the second opening <tr> being right before its closing counterpart instead of before the corresponding <td> tags.

var petsData = [{
    name: "Purrsloud",
    species: "Cat",
    favFoods: ["wet food", "dry food", "<strong>any</strong> food"],
    birthYear: 2016,
    photo: "https://learnwebcode.github.io/json-example/images/cat-2.jpg"
  },
  {
    name: "Barksalot",
    species: "Dog",
    birthYear: 2008,
    photo: "https://learnwebcode.github.io/json-example/images/dog-1.jpg"
  },
  {
    name: "Meowsalot",
    species: "Cat",
    favFoods: ["tuna", "catnip", "celery"],
    birthYear: 2012,
    photo: "https://learnwebcode.github.io/json-example/images/cat-1.jpg"
  }
];

var tableStart = `
  <table>
    <tr>
      <th>Name</th>
      <th>Species</th>
      <th>Birth Year</th>
      <th>Favorite Foods</th>
    </tr>`;
var tableEnd = `
  </table>`;

function foods(foods) {
  return `
<h4>Favorite Foods</h4>
<ul class="foods-list">
${foods.map(food => `<li>${food}</li>`).join("")}
</ul>
`;
}

function petTemplate(pet) {
  return `
      <tr>
        <td>${pet.name}</td>
        <td>${pet.species }</td>
        <td>${pet.birthYear}</td>
        <td>${pet.favFoods ? foods(pet.favFoods) : ""}</td>
      </tr>
  `;
}

document.getElementById("table").innerHTML = `
  ${tableStart}
  ${petsData.map(petTemplate).join("")}
  ${tableEnd}
`;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="table"></div>
like image 161
Constantin Groß Avatar answered Sep 30 '22 05:09

Constantin Groß