Search code examples
javascriptjsonswitch-statementfetchcase

SortBy function not sorting elements


I'm building a web page that fetches JSON data containing information about temples and displays them. I've implemented a dropdown filter that should allow users to filter temples based on their location and dedication date. However, after implementing the filter, it's not updating the displayed temples as expected.

The expected behavior is: When "Utah" is selected, only temples in Utah should be displayed. When "Outside of Utah" is selected, temples outside Utah should be displayed. ... [and so on for other filters]

However, the actual behavior is that all temples are displayed regardless of the selected filter.

I've checked:

  • The fetch is successful and returns the expected data structure.
  • Console logs within the sortBy function indicate that it's being triggered.

Any suggestions on why the filter might not be working as expected or how to debug this issue further?

/* W05: Programming Tasks */

/* Declare and initialize global variables */
const templesElement = document.querySelector('#temples');

let templesList = [];

/* async displayTemples Function */
const displayTemples = (temples) => {
    templesList.forEach(temple => {
        const article = document.createElement('article');
        const templeName = document.createElement('h3');
        templeName.innerHTML = temple.templeName;
        const templeImage = document.createElement('img');
        templeImage.src = temple.imageUrl;
        templeImage.alt = temple.location;
        article.appendChild(templeName);
        article.appendChild(templeImage);
        templesElement.appendChild(article);
    });
   
}

const displayUtahTemples = (temples) => { 
    templesList.forEach(temple => {
        const article = document.createElement('article');
        const templeName = document.createElement('h3');
        templeName.innerHTML = temple.templeName;
        const templeImage = document.createElement('img');
        templeImage.src = temple.imageUrl;
        templeImage.alt = temple.location;
        article.appendChild(templeName);
        article.appendChild(templeImage);
        templesElement.appendChild(article);
        const utahTemples = temples.filter(temple => temple.location.includes('Utah'));
        console.log(utahTemples);
    });
   
}  
displayUtahTemples(templesList);

/* async getTemples Function using fetch()*/
getTemples = async () => {
    const response = await fetch('https://byui-cse.github.io/cse121b-ww-course/resources/temples.json')
    const data = await response.json();
    templesList = data;
    displayTemples(templesList);

}

/* reset Function */
const reset = () => {

    templesElement.textContent = "";
}

// Call the reset function

reset();


// Should log the actual HTML element, not null or undefined


/* sortBy Function */

const sortBy = (temples) => {
    reset();
    

    const compareDate = new Date(1950, 0, 1);
    let filter = document.querySelector('#sortBy').value;
    console.log("sortBy function called with filter:", filter);
    switch (filter) {
        case 'utah':
            displayTemples(temples.filter(temple => temple.location.includes('Utah')));
            console.log(temples);
            break;
        case 'notutah':
            displayTemples(temples.filter(temple => !temple.location.includes('Utah')));
            console.log(temples);
            break;
        case 'older':
            displayTemples(temples.filter(temple => {
                const templeDate = new Date(temple.dedicated.split(', ').reverse().join('-'));
                console.log(temples);
                return templeDate < compareDate;}));
            break;
        case 'all':
            displayTemples(temples);
            break;
        default:
            displayTemples(temples);
    }
};

/* Event Listener */

document.querySelector('#sortBy').addEventListener('change', () => sortBy(templesList));

getTemples();
/* Universal Selector */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

/* HTML Selectors */
body {
    font-family: 'Roboto', Helvetica, sans-serif;
}

nav {
    background-color: black;
    width: 100%;
    position: fixed;
    top: 0;
}

nav ul {
    display: flex;
    flex-direction: column;
    align-items: center;
    max-width: fit-content;
    margin: 0 auto;
}

nav ul li {
    flex: 1 1 auto;
}

nav ul li:first-child {
    display: block;
    font-size: 2rem;
}

nav ul li:first-child a {
    padding: 1px 10px;
}

nav ul li {
    display: none;
    list-style: none;
    margin: 10px;
}

nav ul li a {
    display: block;
    padding: 10px;
    text-decoration: none;
    font-weight: 600;
    color: white;
    text-align: center;
}

nav ul li a:hover {
    background-color: #efefef;
    color: black;
}

h1, h2 {
    text-align: center;
    margin-bottom: 15px;

}

h1 {
border-bottom: 1px solid #ccc;
}

h2 {
    font-size: 1.2rem;
    color: navy;
    text-align: center;
    margin-top: 30px;
}

main {
    margin-top: 125px;
    display: grid;
    grid-template-columns: 1fr;
    grid-gap: 20px;
    align-items: center;
    justify-content: center;
}

picture {
    margin: 0 auto;
}

picture img {
    width: 240px;
    height: auto;
    border-radius: 5%;
    border: 1px solid #ccc;
    box-shadow: 0 0 30px #777;
}

section {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin: 10px
}

label {
    margin: 15px 0;
}

footer {
    background-color: gray;
    color: white;
    padding: 15px;
    text-align: center;
    width: 100%;
    position: fixed;
    bottom: 0;
}

/* Class Selectors */
.active {
    border-bottom: 1px solid yellow;
}

.open li {
    display: block;
}

.block {
    display: block;
}

/* ID Selectors */

/* Media Queries */
@media only screen and (min-width: 32.5em) {
    nav ul {
        flex-direction: row;
    }

    nav ul li:first-child {
        display: none;
    }

    nav ul li {
        display: block;
    }

    main {
        margin: 100px auto 20px;
        grid-template-columns: 250px 1fr;
        max-width: -moz-fit-content;
        max-width: fit-content;

    }



}
dl {
    margin: 0;
    padding: 0;
}

dt {
    font-weight: bold;
    margin: 10px 0;
}

dd {
    margin: 0;
    padding: 0 0 10px 20px; /* Indentation of description */
}


#places-lived {
    margin-bottom: 10%; /* adjust value as needed */
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>CSE 121b | W05: Programming Tasks</title>
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;600&display=swap"
    rel="stylesheet">
  <link rel="stylesheet" href="styles/main.css">
</head>

<body>
  <nav>
    <ul id="menu">
      <li><a id="toggleMenu">&equiv;</a></li>
      <li><a href="index.html">Home</a></li>
      <li><a href="w01-task.html">W1 Task</a></li>
      <li><a href="w03-task.html">W3 Task</a></li>
      <li><a href="w04-task.html">W4 Task</a></li>
      <li><a href="w05-task.html" class="active">W5 Task</a></li>
      <li><a href="project.html">Project</a></li>
    </ul>
  </nav>
  <main id="gridly">
    <h1>W05: Programming Tasks</h1>
    <h2>Fetch(): Some Latter-day Temples</h2>

    <select id="sortBy" title="Choose a data filter.">
      <option value="" disabled selected>Filter Temples</option>
      <option value="utah">Utah</option>
      <option value="notutah">Outside of Utah</option>
      <option value="older">Built Before 1950</option>
      <option value="all">No Filter</option>
    </select>

    <div id="temples">
    </div>
  </main>


  <footer>
    &copy;<span id="year"></span> | Week 05 - Fetching Temple Data | CSE 121b
  </footer>
  <script src="scripts/main.js"></script>
  <script>
    document.getElementById("year").innerHTML = new Date().getFullYear();
  </script>
  <script src="scripts/w05-task.js"></script>
</body>

</html>

Solution

  • well the function is not changing the values of the templeslist array, so when the displayutahtemples function is called, it always displays all the temples. To fix this issue, the sortBy function should first update the templeslist array with the filtered values, and then call the displaytemples function with the updated array.

    const sortBy = (temples) => {
        reset();
    
        const compareDate = new Date(1950, 0, 1);
        let filter = document.querySelector('#sortBy').value;
        console.log("sortBy function called with filter:", filter);
    
        switch (filter) {
            case 'utah':
                templesList = temples.filter(temple => temple.location.includes('Utah'));
                break;
            case 'notutah':
                templesList = temples.filter(temple => !temple.location.includes('Utah'));
                break;
            case 'older':
                templesList = temples.filter(temple => {
                    const templeDate = new Date(temple.dedicated.split(', ').reverse().join('-'));
                    return templeDate < compareDate;
                });
                break;
            default:
                templesList = temples;
        }
    
        displayTemples(templesList);
    };