This tutorial introduces you to a JavaScript technique for creating records in a web page from an external file written in JSON (JavaScript Object Notation). We assume you know some HTML and enough JavaScript to understand objects and JSON.
Note: this draft presents only a synopsis of this tutorial. Please watch the video for details.
Imagine your ideal card and write it out as sample HTML
<div class="card">
<img src="pad_thai.jpg" />
<h4>Pad Thai</h4>
<h5>Thai - 25 minutes</h5>
<p class="description">A tangy stir fry from Thailand.</p>
</div>
Write a factory function to make the card from your JSON
Note the backticks: return (`<div>...</div>`)
recipe => {
return (
`<div class="card">
<img src="${recipe["image"]}" />
<h4>${recipe["dish"]}</h4>
<h5>${recipe["ethnicity"]} - ${recipe["cookingTimeInMinutes"]} minutes</h5>
<p class="description">${recipe["description"]}</p>
</div>`
)
}
Create a map function to build those cards from your JSON array (remember enclosing backticks).
recipesHTML = recipes.map(
recipe => {
return (
`<div class="card">
<img src="${recipe["image"]}" />
<h4>${recipe["dish"]}</h4>
<h5>${recipe["ethnicity"]} - ${recipe["cookingTimeInMinutes"]} minutes</h5>
<p class="description">${recipe["description"]}</p>
</div>`
)
}
)
Write an asynchronous function to get your data:
const buildCardsFromData = async () => {
let response = await fetch("recipes.json") ;
let recipeJSON = await response.json() ;
}
Put async in the function declaration at top, then await anytime you have to wait for the data.
Then map out the cards, then show them on your device.
// Add "async" to the function declaration to enable it to wait for server data.
// Note the special placement of the word for arrow function syntax.
const buildCardsFromData = async () => {
// Put the word "await" before any command that requires waiting for data to load.
let response = await fetch("recipes.json") ;
let recipeJSON = await response.json() ;
// From here down, everything is client-side, so we don't need the "await" keyword anymore.
// We'll make cards from each item in our recipeJSON array.
// Below is a quick-and-dirty way to make divs from your JSON,
// just by loading HTML tags into a big string variable.
recipesHTML = recipeJSON.map(
recipe => {
return (
`<div class="card">
<img src="${recipe["image"]}" />
<h4>${recipe["dish"]}</h4>
<h5>${recipe["ethnicity"]} - ${recipe["cookingTimeInMinutes"]} minutes</h5>
<p class="description">${recipe["description"]}</p>
</div>`
)
}
) ;
// Let's log the result to make sure our JSON is converting to HTML correctly.
// You'll see weird line breaks because of the way we formatted our text above.
console.log( '%c recipesHTML is ' + recipesHTML, 'color: blue; background:azure ; font-style: italic; font-weight: bold;' ) ;
// Now we will just add each of these cards to our container.
recipesHTML.forEach(
recipe => {
document.getElementById("device").innerHTML += recipe ;
}
)
}
Use .then to wait for the data, then map out the cards, then show them on your device.
More verbose, but it fits well with .catching errors.
fetch("recipes.json")
.then(
data => {
return data.json()
}
)
.then(
json => {
json.map(
// Turn JSON into HTML tags...
)
}
)
.then(
// Add the HTML tags to the document...
)
⚠️ Catching errors is a little more convenient with the .then syntax.
⚠️ You need to put your card-building HTML file on the same server as your JSON file, or browsers will throw a Cross-Origin Resource Sharing (CORS) error.