Just-in-Time Learning: tutorial script

Version 1.1

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.

👆Demo that builds cards from data

Write a sample card in HTML

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>
	

Convert the sample data into JavaScript template

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>`
	)
}
	

Apply this template repeatedly to an array of data

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>`
		)
	}
)
	

Create the array from your JSON

Write an asynchronous function to get your data:


const buildCardsFromData = async () => {
	let response = await fetch("recipes.json") ;
	let recipeJSON = await response.json() ;
}
	

Put it all together

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 ;
		}
	)
}
		

Alternative .then syntax:

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...
)
	

Warnings

⚠️ 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.

Reminders