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.
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.
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.
"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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With