The Fetch API
Overview
The objective of the activity is for you to work with the Fetch API and data stored in JSON format to create a page of content dynamically.
"The Fetch API provides a JavaScript interface for accessing and manipulating parts of the protocol, such as requests and responses. It also provides a global fetch() method that provides an easy, logical way to fetch resources asynchronously across the network." - MDN
Prepare
We are going to use the fetch() method which requires at least one argument, the path to the resource. The fetch() method then returns an asynchronous Promise that provides a generic Response to the request.
- The fetch() method is part of the Fetch API.
- The fetch() method can be used within an async function which means that we will allow the data retrieval to happen before trying to continue with statements in our program that need to process the data. A promise for data is one thing, but the actual data is what is really needed, so we need a delay. Async/await provide that promised-based asynchronous behavior.
- We need to extract the JSON content from the noise of the full HTTP response by using the json() method. With the string data retrieved, we can run a .json() method on the Response to convert it into a JavaScript object, which is easy to work with.
- The fetch() method has built in error handling.
- Read: 📃 Fetch Basics
Activity Instructions
Work with your group as you run into issues or have questions with learning activities. You should be receiving notifications of posts made in your group's Microsoft Teams channel.
In this activity you will build a responsive page that will display a list of the latter-day prophets.
Setup
- In your wdd231 folder, create a new file named "prophets.html".
- Add a file named "prophets.css" and a file name "prophets.js" into their appropriate folders.
HTML
- In the prophets.html file, structure the page using valid html and meta information.
- Link style references.
- Add the following HTML to your
<body>
element.<header> <h1>Latter-day Prophets</h1> </header> <main> <div id="cards"></div> </main> <footer> [Enter Your Name Here] | Latter-day Prophets </footer>
JavaScript
- Open this file in your browser to identify and reference the key/value pairs found in the JSON data. https://brotherblazzard.github.io/canvas-content/latter-day-prophets.json.
- Declare a const variable named "url" that contains the URL string of the JSON resource provided.
const url = 'https://brotherblazzard.github.io/canvas-content/latter-day-prophets.json';
- Declare a const variable name "cards" that selects the HTML div element
from the document with an id value of "cards".
const cards = document.querySelector('#cards');
- Create a async defined function named "getProphetData" to fetch data from the JSON source url using the await fetch() method.
- Store the response from the fetch() method in a const variable named "response".
- Convert the response to a JSON object using the .json method and store the results in a const variable named "data".
- Add a console.table() expression method to check the data response at this point in the console window.
- Call the function getProphetData() in the main line of your .js code to test the fetch and
response.
Check Your Understanding - Example
async function getProphetData() { const response = await fetch(url); const data = await response.json(); console.table(data.prophets); // temporary testing of data response } getProphetData();
Do you remember how to check the output in the console window in DevTools? Hopefully everything checks out and you see data on the latter-day prophets neatly organized in a console table or log view. We will comment out this line of console line of code when we are done or just remove the line of code.
- If it all checks out, note that the data returns a single property, an array of objects named "prophets".
- Comment out the console line and call a function named "displayProphets"
and
include the "data.prophets" argument. Why do we send data.prophets
versus just the data variable? The displayProphets() function expects an array
parameter.
Check Your Understanding - Example
async function getProphetData(url) { const response = await fetch(url); const data = await response.json(); //console.table(data.prophets); displayProphets(data.prophets); // note that we reference the prophets array of the JSON data object, not just the object } getProphetData();
- Define a function expression named "displayProphets" that handles a single parameter named
"prophets" somewhere in your js file. Use an arrow expression to contain statements that will
process the parameter value and build a card for each
prophet.
const displayProphets = (prophets) => { // card build code goes here }
Remember that functions are hoisted and therefore, where ever you define the function in your main line of code does not matter as it is available to the rest of the scoped code.
- Inside the function, use a forEach loop with the array parameter to process each
"prophet" record one at a time, creating a new card each time.
const displayProphets = (prophets) => { prophets.forEach((prophet) => { }); }
- Inside the HTML card building loop, do the following:
- create a section element and store it in a variable named card using createElement(),
- create an h2 element and store it in a variable named "fullName",
- create an img element and store it in a variable named "portrait",
- populate the heading element with the prophet's full name using a template string to build the full name,
- build the image element by setting the
- src,
- alt,
- loading,
- width, and
- height attributes using setAttribute().
- Using appendChild() on the section element named "card", add the heading and image elements one at a time.
- Finally, add the section card to the "cards" div that was selected at the beginning of
the script file.
Check Your Understanding - Example (With blanks to fill in)
const displayProphets = (prophets) => { prophets.forEach((prophet) => { // Create elements to add to the div.cards element let card = document.createElement('section'); let fullName = document.createElement('__'); // fill in the blank let portrait = document.createElement('img'); // Build the h2 content out to show the prophet's full name fullName.textContent = `${prophet._____} ____________`; // fill in the blank // Build the image portrait by setting all the relevant attributes portrait.setAttribute('src', prophet.imageurl); portrait.setAttribute('alt', `Portrait of ${prophet.____} ______________`); // fill in the blank portrait.setAttribute('loading', 'lazy'); portrait.setAttribute('width', '340'); portrait.setAttribute('height', '440'); // Append the section(card) with the created elements card.appendChild(_______); //fill in the blank card.appendChild(portrait); cards.appendChild(card); }); // end of arrow function and forEach loop }
Seek Mastery
- Refactor the image alternative text and add the prophet number at the end of the prophet
name,
for example,alt="Portrait of Heber J. Grant - 7th Latter-day President"
- Add buttons that allow the user to filter the data for things like:
- Prophets who were born in Utah.
- Prophets who were born outside of the United States.
- Prophets who lived to 95+ years.
- Prophets who have 10 or more children.
- Prophets who served as president of the church for at least 15 years.
CodePen Example: ⚙️ Filter Buttons
- What other improvements could be made to the application?
Test and Style and Share
- Test the output and then add the remaining information as shown in the screenshot examples.
- Add page styling using the external CSS file by attempting to replicate, using your own colors and font choices, the layout shown in the example screenshots.
- Using a CSS Grid, use the auto-fit value to ensure that the page is responsive.
Example: CSS Grid - Responsive Columns using autofit.
- Add the Date of Birth and Place of Birth as shown in the screenshot at the start of this activity.
- Share your work with the course on Microsoft Teams and/or your group.
Optional Resources
- JavaScript Fetch API For Beginners - freecodecamp.org