Skip to content

Commit

Permalink
Allow for retries
Browse files Browse the repository at this point in the history
  • Loading branch information
jimchamp committed Feb 27, 2024
1 parent 0557ef7 commit 80b6298
Showing 1 changed file with 53 additions and 24 deletions.
77 changes: 53 additions & 24 deletions openlibrary/plugins/openlibrary/js/affiliate-links.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
/**
* Replaces loading indicators with partially rendered affiliate links.
* Adds functionality to fetch affialite links asyncronously.
*
* Fetches and attaches partials to DOM iff any of the given affiliate link
* sections contain a loading indicator.
* Fetches and attaches partials to DOM _iff_ any of the given affiliate link
* sections contain a loading indicator. Adds affordance for retrying if the
* call for partials fails.
*
* @param {NodeList<HTMLElement>} affiliateLinksSections
* @param {NodeList<HTMLElement>} affiliateLinksSections Collection of each affiliate links section that is on the page
*/
export function initAffiliateLinks(affiliateLinksSections) {
const isLoading = showLoadingIndicators(affiliateLinksSections)
Expand All @@ -16,24 +17,7 @@ export function initAffiliateLinks(affiliateLinksSections) {
const args = [title, opts]
const d = {args: args}

getPartials(d)
.then((resp) => {
if (resp.status !== 200) {
throw new Error(`Failed to fetch partials. Status code: ${resp.status}`)
}
return resp.json()
})
.then((data) => {
const span = document.createElement('span')
span.innerHTML = data['partials']
const links = span.firstElementChild
for (const section of affiliateLinksSections) {
section.replaceWith(links.cloneNode(true))
}
})
.catch((error) => {
// XXX : Handle errors sensibly
})
getPartials(d, affiliateLinksSections)
}
}

Expand All @@ -60,11 +44,56 @@ function showLoadingIndicators(linkSections) {
* Fetches rendered affiliate links template using the given arguments.
*
* @param {object} data Contains array of positional arguments for the template
* @returns {Promise<Response>}
* @param {NodeList<HTMLElement>} affiliateLinksSections
* @returns {Promise}
*/
async function getPartials(data) {
async function getPartials(data, affiliateLinksSections) {
const dataString = JSON.stringify(data)
const dataQueryParam = encodeURIComponent(dataString)

return fetch(`/partials.json?_component=AffiliateLinks&data=${dataQueryParam}`)
.then((resp) => {
if (resp.status !== 200) {
throw new Error(`Failed to fetch partials. Status code: ${resp.status}`)
}
return resp.json()
})
.then((data) => {
const span = document.createElement('span')
span.innerHTML = data['partials']
const links = span.firstElementChild
for (const section of affiliateLinksSections) {
section.replaceWith(links.cloneNode(true))
}
})
.catch(() => {
// XXX : Handle errors sensibly
for (const section of affiliateLinksSections) {
const loadingIndicator = section.querySelector('.loadingIndicator')
if (loadingIndicator) {
loadingIndicator.classList.add('hidden')
}

const existingRetryAffordance = section.querySelector('.affiliate-links-section__retry')
if (existingRetryAffordance) {
existingRetryAffordance.classList.remove('hidden')
} else {
section.insertAdjacentHTML('afterbegin', renderRetryLink())
const retryAffordance = section.querySelector('.affiliate-links-section__retry')
retryAffordance.addEventListener('click', () => {
retryAffordance.classList.add('hidden')
getPartials(data, affiliateLinksSections)
})
}
}
})
}

/**
* Returns HTML string with error message and retry link.
*
* @returns {string} HTML for a retry link.
*/
function renderRetryLink() {
return '<span class="affiliate-links-section__retry">Failed to fetch affiliate links. <a href="javascript:;">Retry?</a></span>'
}

0 comments on commit 80b6298

Please sign in to comment.