🛠️ Infinite Scroll: Refactor
Read through the code we wrote together. Does the zlFetch
blocks of code stand out to you?
They stand out because they do almost the same things. The initial zlFetch
block contains a subset of the subsequent zlFetch
block.
// Initial Fetch
zlFetch(`${endpoint}?limit=6&page=1`)
.then(response => {
// Add letters to DOM
// Hide spinner
// Change button.dataset.nextPage
})
// Subsequent Fetches
loadMoreButton.addEventListener('click', event => {
// Show spinner
// Hide button
zlFetch(loadMoreButton.dataset.nextPage)
.then(response => {
// Add letters to DOM
// Hide spinner
// Show button
// Change button.dataset.nextPage
// If there's no more content, show Dribbble section
})
})
In this case, we can put both zlFetch
blocks into a single function called fetchLetters
.
const fetchLetters = _ => {
// Show spinner
// Hide button
zlFetch(loadMoreButton.dataset.nextPage)
.then(response => {
// Add letters to DOM
// Hide spinner
// Show button
// Change button.dataset.nextPage
// If there's no more content, show Dribbble section
})
}
We can use fetchLetters
like this:
loadMoreButton.addEventListener('click', fetchLetters)
loadMoreButton.dataset.nextPage = `${endpoint}?limit=6&page=1`
loadMoreButton.click()
Improving fetchLetters
fetchLetters
contains a huge chunk of code.
const fetchLetters = _ => {
// Show spinner
// Hide button
zlFetch(loadMoreButton.dataset.nextPage)
.then(response => {
// Add letters to DOM
// Hide spinner
// Show button
// Change button.dataset.nextPage
// If there's no more content, show Dribbble section
})
}
The part where we add letters to DOM contains a chunk of code. We can extract it into a separate function to make fetchLetters
easier to understand.
We’ll call this new function addLettersToDOM
.
const addLettersToDOM = letters => {
const fragment = document.createDocumentFragment()
letters.forEach(letter => {
const li = document.createElement('li')
li.innerHTML = `
<a class="letter" href="${letter.shotUrl}">
<span>By ${letter.creator}</span>
<img src="${letter.imageUrl}" alt="Picture of ${letter.letter}" width="400" height="300">
</a>
`
fragment.appendChild(li)
})
lettersElement.appendChild(fragment)
}
Using addLettersToDOM
:
const fetchLetters = _ => {
// Show spinner
// Hide button
zlFetch(loadMoreButton.dataset.nextPage)
.then(response => {
const { nextPage, letters } = response.body
addLettersToDOM(letters)
// Hide spinner
// Show button
// Change button.dataset.nextPage
// If there's no more content, show Dribbble section
})
}
showElement
and hideElement
We can also create showElement
and hideElement
functions to help us set and remove the hidden
attribute.
const hideElement = element => {
element.setAttribute('hidden', true)
}
const showElement = element => {
element.removeAttribute('hidden')
}
Using them:
const fetchLetters = _ => {
showElement(spinner)
hideElement(loadMoreButton)
zlFetch(loadMoreButton.dataset.nextPage)
.then(response => {
const { nextPage, letters } = response.body
addLettersToDOM(letters)
hideElement(spinner)
showElement(loadMoreButton)
if (nextPage) {
loadMoreButton.dataset.nextPage = nextPage
} else {
hideElement(loadMoreButton)
showElement(dribbbleSection)
}
})
}
That’s it!