The Code

                    
                    // Test Data
                    const events = [
                    {
                        event: "ComicCon",
                        city: "New York",
                        state: "New York",
                        attendance: 240000,
                        date: "06/01/2017",
                    },
                    {
                        event: "ComicCon",
                        city: "New York",
                        state: "New York",
                        attendance: 250000,
                        date: "06/01/2018",
                    },
                    {
                        event: "ComicCon",
                        city: "New York",
                        state: "New York",
                        attendance: 257000,
                        date: "06/01/2019",
                    },
                    {
                        event: "ComicCon",
                        city: "San Diego",
                        state: "California",
                        attendance: 130000,
                        date: "06/01/2017",
                    },
                    {
                        event: "ComicCon",
                        city: "San Diego",
                        state: "California",
                        attendance: 140000,
                        date: "06/01/2018",
                    },
                    {
                        event: "ComicCon",
                        city: "San Diego",
                        state: "California",
                        attendance: 150000,
                        date: "06/01/2019",
                    },
                    {
                        event: "HeroesCon",
                        city: "Charlotte",
                        state: "North Carolina",
                        attendance: 40000,
                        date: "06/01/2017",
                    },
                    {
                        event: "HeroesCon",
                        city: "Charlotte",
                        state: "North Carolina",
                        attendance: 45000,
                        date: "06/01/2018",
                    },
                    {
                        event: "HeroesCon",
                        city: "Charlotte",
                        state: "North Carolina",
                        attendance: 50000,
                        date: "06/01/2019",
                    }];
                    
                    // Entry point of application, runs when the page loads
                    function buildDropDown() {
                    
                        // get all the events that we know about
                        let currentEvents = getEvents();
                    
                        // get a list of city names, using map and lambda expression
                        let eventCities = currentEvents.map(event => event.city);
                    
                        // Class constructor, take array of event cities which has dups and store only unique values as a set
                        let uniqueCities = new Set(eventCities);
                    
                        // spread operator [...], takes the set and spreads it out into another array with 'All' added at index 0
                        let dropdownChoices = ['All', ...uniqueCities];
                    
                        // Get template for dropdown before looping over each item
                        const dropdownTemplate = document.getElementById('dropdown-item-template');
                    
                        const dropdownMenu = document.getElementById('city-dropdown');
                    
                        // Clear out what's already in the menu before adding
                        dropdownMenu.innerHTML = '';
                    
                        // for each of those city names:
                        for ( let i=0; i < dropdownChoices.length; i++) {
                    
                            let cityName = dropdownChoices[i];
                    
                            // make a dropdown item HTML element
                            let dropdownItem = dropdownTemplate.content.cloneNode(true);
                            dropdownItem.querySelector('a').innerText = cityName;
                        
                            // add that element to the dropdown menu
                            dropdownMenu.appendChild(dropdownItem);
                        }
                        
                        displayEvents(currentEvents);
                    
                        displayStats(currentEvents);
                    
                        // reset table header name
                        document.getElementById('stats-location').textContent = 'All';
                    }
                    
                    // Grabs the latest events
                    function getEvents() {
                        // get events from local storage
                        let eventsJson = localStorage.getItem('rpc-events');
                    
                        // initialize stored events if someone hasn't been to the page before
                        let storedEvents = events;
                    
                        // check for events have been saved before
                        if (eventsJson == null) {
                            saveEvents(events);
                        } else {
                            storedEvents = JSON.parse(eventsJson);
                        }
                    
                        return storedEvents;
                    }
                    
                    // Save event added in modal to local storage
                    function saveEvents(events) {
                    
                        let eventsJson = JSON.stringify(events);
                    
                        // store in the browser for undetermined amount of time, can be seen and modified by anyone
                        localStorage.setItem('rpc-events', eventsJson);
                    }
                    

                    function displayEvents(events) {
                    
                        // get the table to put the events in
                        const eventTable = document.getElementById('eventsTable');
                    
                        // clear the table
                        eventTable.innerHTML = '';
                    
                        // loop through events
                        for (let i = 0; i < events.length ; i++) {
                    
                            let event = events[i];
                    
                            // make a <tr></tr>
                            let eventRow = document.createElement('tr');
                    
                            // make a <td> for each property
                            // put the data into each <td> & append to row
                            let eventName = document.createElement('td');
                            eventName.innerText = event.event;
                            eventRow.appendChild(eventName);
                    
                            let eventCity = document.createElement('td');
                            eventCity.innerText = event.city;
                            eventRow.appendChild(eventCity);
                    
                            let eventState = document.createElement('td');
                            eventState.innerText = event.state;
                            eventRow.appendChild(eventState);
                    
                            let eventAttendance = document.createElement('td');
                            eventAttendance.innerText = event.attendance.toLocaleString();
                            eventRow.appendChild(eventAttendance);
                    
                            let eventDate = document.createElement('td');
                    
                            let date = new Date(event.date);
                    
                            eventDate.innerText = date.toLocaleDateString();
                            eventRow.appendChild(eventDate);
                            
                            // append the row to the <tbody>
                            eventTable.appendChild(eventRow);
                        }
                    }
                    
                    function calculateStats(events) {
                    
                        let sum = 0;
                        let min = events[0].attendance;
                        let max = 0;
                    
                        for(let i = 0; i < events.length; i++) {
                            let event = events[i];
                    
                            sum += event.attendance;
                    
                            // Checks for the min attendance
                            if ( event.attendance < min ) {
                                min = event.attendance;
                            }
                    
                            // Checks for the max attendance
                            if ( event.attendance > max ) {
                                max = event.attendance;
                            }
                        }
                    
                        let avg = sum / events.length;
                    
                        // Shorter way to type objects if the properties are the same as the variable values
                        let stats = {
                            sum,
                            avg,
                            min,
                            max
                        }
                        return stats;
                    }
                    
                    function displayStats(events) {
                    
                        let stats = calculateStats(events);
                        // calculating and displaying the total attendance
                        document.getElementById('total-attendance').innerText = stats.sum.toLocaleString();
                    
                        // calculating and displaying the avg attendance
                        document.getElementById('avg-attendance').innerText = stats.avg.toLocaleString();
                    
                        // calculating and displaying and displaying the max attendance
                        document.getElementById('max-attended').innerText = stats.max.toLocaleString();
                    
                        // // calculating and displaying and displaying the min attendance
                        document.getElementById('min-attended').innerText = stats.min.toLocaleString();
                    }
                    
                    function filterByCity(element) {
                    
                        // get all the events
                        let cityName = element.textContent;
                    
                        // revise table header name
                        document.getElementById('stats-location').textContent = cityName;
                    
                        // get all the events
                        let allEvents = getEvents();
                    
                        // filter those events to just one city
                        let filteredEvents = [];
                    
                        for (let i = 0; i < allEvents.length; i++) {
                            let event = allEvents[i];
                    
                            if ( cityName == event.city || cityName == 'All' ) {
                                filteredEvents.push(event);
                            }
                    
                            // OTHER OPTION TYPE 1: Anonymous function with the filter method can be used to filter the array
                            // filteredEvents = allEvents.filter(function(event) {
                            //     if (event.city == cityName || cityName == 'All') {
                            //         return event;
                            //     } 
                            // })
                    
                            // OTHER OPTION TYPE 2: Lambda expression with the filter method can be used to filter the array below is the same as the for loop 
                            // if (cityName == 'All') {
                            //     filteredEvents = allEvents;
                            // } else {
                            //     filteredEvents = allEvents.filter(event => event.city == cityName)
                            // }
                        
                            // OTHER OPTION TYPE 3: Ternary statement
                            // let filteredEvents = cityName = 'All' ? allEvents : allEvents.filter(e => e.city == cityName);
                        }
                    
                        // call displayStats with the events for that city
                        displayStats(filteredEvents);
                    
                        // call displayEvents with the events for that city
                        displayEvents(filteredEvents);
                    }
                    
                    function saveNewEvent() {
                    
                        // Get HTML form element
                        let newEventForm = document.getElementById('newEventForm');
                        let formData = new FormData(newEventForm);
                    
                        // Creates an object from the <input>s
                        // value of the property is the value of the input and the property is the name
                        // <input name="city" value="kernersville" />
                        // let newEvent = { city: 'Kernersville}
                        let newEvent = Object.fromEntries(formData.entries());
                    
                        // change text to number for attendance
                        newEvent.attendance = parseInt(newEvent.attendance);
                    
                        // make sure all dates recieved are consistent in the way they're recieved
                        newEvent.date = new Date(newEvent.date).toLocaleDateString();
                    
                        // Grab the list of events
                        let allEvents = getEvents();
                    
                        // Add new event to list
                        allEvents.push(newEvent);
                    
                        // Save updated list of events
                        saveEvents(allEvents);
                    
                        // Resets the form so it goes back to how it was when page loaded
                        newEventForm.reset();
                    
                        displayEvents(allEvents);
                    
                        // hide the Bootstrap Modal
                        let modalElement = document.getElementById('addEventModal');
                        let bsModal = bootstrap.Modal.getInstance(modalElement);
                        bsModal.hide();
                    
                        // display all events
                        buildDropDown();
                    }
                    
                

TL;DR

Use localStorage.setItem() & localStorage.getItem() to store information in the browser. This information is only accessible on the same browser it was saved in.

Code Explanation

Bash Buddy was created with the following functions:

buildDropDown

getEvents

saveEvents

displayEvents

calculateStats

displayStats

filterByCity

saveNewEvent

What I learned

  • Use map to easily create an array of a spcific property from an array of objects
  • Use Set to provide an array that only contains unique values
  • localStorage.setItem() & localStorage.getItem() allows for storing and then getting information in the browser as a JSON for an undetermined amount of time. This stoarge can be viewed and modified by anyone who has access to the same browserthe information was stored in.

Improvements

  • Ability to delete one / all events
  • Ability to filter by Event Name / Type, Date
  • Set up initial data with an API