Table of Contents
Now the fun part! We'll write some HTML, then create the JavaScript code to pull down a list of Bibles versions from the API.
HTML - index.html
The first file is index.html
. This page shows a list of all Bible version that are accessible to the provided API Key. Different API Keys have access to different Bible versions.
The HTML is below. We'll point out a few key things in the HTML, but we'll explain a lot more when we get to the JavaScript.
<!DOCTYPE html><html><head><link href="css/main.css" rel="stylesheet" /><title>Bible API Example Application</title></head><body class="index"><header><div class="container"><h1><a class="flex" href="/"><span class="logo" title="American Bible Society">ABS</span><span>API Demo App</span></a></h1></div></header><div class="subheader"><div class="container flex"><div class="subheadings"><h2>Select a</h2><h3>Bible</h3></div></div></div><main class="container"><div id="bible-version-list" class="list-container bible-list"></div></main><script src="js/my_key.js"></script><script>// JAVASCRIPT GOES HERE</script></body></html>
One thing to notice in this file is that we link to our other required files. In the head there is a link to one of the css files, css/main.css
. We don't need scripture.css
yet since this page does not display any verses. Toward the end we link to js/my_key.js
. It is best practice to put JavaScript toward the end of an HTML file.
This HTML also includes a div that we are going to fill using JavaScript. The list of Bibles will be put into the div toward the end with id="bible-version-list"
.
JavaScript - index.html
Now we'll start building out the JavaScript. This is where the API is used. All the JavaScipt below should be inserted in the index.html
file where it says JAVASCRIPT GOES HERE
.
const versionList = document.querySelector(`#bible-version-list`);let versionHTML = ``;getBibleVersions().then((bibleVersionList) => {const sortedVersions = sortVersionsByLanguage(bibleVersionList);for (let languageGroup in sortedVersions) {const language = languageGroup;versionHTML += `<h4 class="list-heading"><span>${language}</span></h4><ul>`;const versions = sortedVersions[languageGroup];for (let version of versions) {versionHTML += `<li class="bible"><a href="book.html?version=${version.id}&abbr=${version.abbreviation}"><abbr class="bible-version-abbr" title="${version.name}">${version.abbreviation}</abbr><span><span class="bible-version-name">${version.name}</span>${version.description? '<span class="bible-version-desc">' +version.description +"</span>": ""}</span></a></li>`;}versionHTML += `</ul>`;}versionList.innerHTML = versionHTML;});
The code above builds the HTML containing the list of Bible versions and then inserts it into the page. Line 3 gets the list of Bible versions by calling the function getBibleVersions()
. This is where the API call actually happens. Next, line 4 sorts the list by calling the function sortVersionsByLanguage
. Those functions are defined below.
In the HTML, each Bible version name is a link to a list of Bible books using that version. Here is the format of the link: book.html?version=${version.id}&abbr=${version.abbreviation}
. For this website, we chose to pass information between pages using query parameters. However, there are other ways to do this.
Remember, all these code snippets should go in
index.html
where it saysJAVASCRIPT GOES HERE
, one after the other."
function getBibleVersions() {return new Promise((resolve, reject) => {const xhr = new XMLHttpRequest();xhr.withCredentials = false;xhr.addEventListener(`readystatechange`, function () {if (this.readyState === this.DONE) {const { data } = JSON.parse(this.responseText);const versions = data.map((data) => {return {name: data.name,id: data.id,abbreviation: data.abbreviation,description: data.description,language: data.language.name,};});resolve(versions);}});xhr.open(`GET`, `https://api.scripture.api.bible/v1/bibles`);xhr.setRequestHeader(`api-key`, API_KEY);xhr.onerror = () => reject(xhr.statusText);xhr.send();});}
The code above is what creates the API call and returns a list of Bible versions. The getBibleVersions
function could have returned everything sent back by the API, but instead it only returns what is needed for our use case. The fields returned by the function are name
, id
, abbreviation
, and language.name
. To learn what other information is returned from the API, check out the Bibles section of the API reference.
This function returns a Promise. Returning a promise makes sure the program will wait until data is returned from the API before attempting to do something with the data.
The most important part of this API request is on line 23. That is where we specify the URL of the API endpoint to get the list of Bible versions. The URL will be different for each API request on our website, depending on what information we want from the API.
Next up is a helper function to sort the Bible versions by language. This is by no means required, but it is a good demonstration of how the API data can be sorted for different purposes.
function sortVersionsByLanguage(bibleVersionList) {let sortedVersions = {};for (const version of bibleVersionList) {if (!sortedVersions[version.language]) {sortedVersions[version.language] = [];}sortedVersions[version.language].push(version);}for (const version in sortedVersions) {sortedVersions[version].sort((a, b) => {const nameA = a.abbreviation.toUpperCase();const nameB = b.abbreviation.toUpperCase();if (nameA < nameB) {return -1;}if (nameA > nameB) {return 1;}return 0;});}return sortedVersions;}
The function above takes as input what the getBibleVersions
function returns. It's a pretty straightforward way to sort an object in JavaScipt. The function creates and returns a new object that has a key for each language from the passed-in list. The value of each key is an array of all Bible versions that use the given language.
And we're done with the first page of our site! The other pages have a lot of similarity to this one, so if you have been following along so far the rest of this tutorial should be easy.