When we click an item in the sidebar we want to make that the active element (we remove the active class from all the other elements and add it to the one just clicked).

Also, we’ll perform a fetch request to the backend, we’ll create a simple API endpoint that returns the data as JSON, optionally filtered by site, so if we pass the site as parameter we get that filtered.

Last, we’ll update the DOM with the new data.

Let’s go!

First we intercept the click event on any sidebar item, and we assign to the active class to the element clicked:

const sidebarLinks = document.querySelectorAll("#sidebar li")

for (const sidebarLink of sidebarLinks) {
  sidebarLink.addEventListener('click', function(event) {
    for (const sidebarLink of sidebarLinks) {
      sidebarLink.classList.remove('active')
    }
    this.classList.add('active')
  })
}

Then we filter the data.

We create a fetchStats() function to ask the server that specific site data:

const fetchStats = site => {
  fetch('/stats?site=' + encodeURIComponent(site)).then(response => {
    //...
  })
  .catch(err => console.error(err))
}

We call this function in the event listener, passing the text contained in the sidebar item (referenced using textContent):

const sidebarLinks = document.querySelectorAll("#sidebar li")

for (const sidebarLink of sidebarLinks) {
  sidebarLink.addEventListener('click', function(event) {
    for (const sidebarLink of sidebarLinks) {
      sidebarLink.classList.remove('active')
    }
    this.classList.add('active')
    fetchStats(this.textContent)
  })
}

On the server side, we listen on the /stats endpoint and based on the site query parameter, we return either all the data, or we filter the data to only return a specific site data:

app.get('/stats', (req, res) => {
  const site = req.query.site

  if (site === 'All') {
    res.json(data.sums)
    return
  } else {
    const filteredData = data.aggregate.filter(item => item.property.name === site)
    res.json(filteredData[0])
  }
})

Now we need to alter the data in the DOM.

We can do it in the fetchStats() function callback. We first parse the JSON response using

fetch('/stats?site=' + encodeURIComponent(site))
  .then(response => response.json())
  .then(body => {

  })

and inside the last then we can access the body values. We’ll assign them to each DOM element using innerText:

const fetchStats = (site) => {
  fetch('/stats?site=' + encodeURIComponent(site)).then(response => response.json())
    .then(body => {
    document.querySelector('#today .total').innerText = body.today.total
    document.querySelector('#today .organic').innerText = body.today.organic
    document.querySelector('#yesterday .total').innerText = body.yesterday.total
    document.querySelector('#yesterday .organic').innerText = body.yesterday.organic
    document.querySelector('#monthly .total').innerText = body.monthly.total
    document.querySelector('#monthly .organic').innerText = body.monthly.organic
  })
  .catch(err => console.error(err))
}

We’re done! We can now see the values update when we click a site on the sidebar.

The full code is available at https://glitch.com/edit/#!/node-course-project-analytics-dashboard-e and the app working is at https://node-course-project-analytics-dashboard-e.glitch.me/


Go to the next lesson