🛠️ Infinite Scroll: Refactor

Hey ,

I'm thrilled to help you learn JavaScript. Unfortunately, you've landed on a page where you cannot access with your current purchase.

Please upgrade (use this link) access this content.

I'm super eager to help you learn more!

🛠️ 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!