'Javascript array filter seems to work, but doesn't print to screen

  1. 4 years are added to the array (2001, 1999, 2000 and 2002)
  2. The array is printed to screen, showing the same 4 years
  3. The maximum year is calculated as 2002
  4. The year 2002 is deleted from the array
  5. The array is printed to screen, but still showing 4 years
  6. Nevertheless, the maximum year is calculated as 2001, indicating that 2002 was actually deleted

What's going on?

const output = document.getElementById('output');

function handleYears() {
    let years = [];
    let addYear = function(newYear) {
        years.push(newYear);
    }
    let deleteYear = function(yearToDelete) {
        years = years.filter(item => item !== yearToDelete)
    }
    let calculateMaxYear = function() {
        return Math.max(...years);
    }

    return {
        years: years,
        addYear: addYear,
        deleteYear: deleteYear,
        calculateMaxYear: calculateMaxYear
    }
}

let newHandleYears = handleYears();

newHandleYears.addYear(2001);
newHandleYears.addYear(1999);
newHandleYears.addYear(2000);
newHandleYears.addYear(2002);

output.innerHTML += `<p>Years: ${newHandleYears.years}</p>`;
output.innerHTML += `<p>Maximum year: ${newHandleYears.calculateMaxYear()}</p>`;
output.innerHTML += `<p>Delete item "${newHandleYears.years[newHandleYears.years.length - 1]}" from "years" array.</p>`;

newHandleYears.deleteYear(2002);

output.innerHTML += `<p>Years: ${newHandleYears.years}</p>`;
output.innerHTML += `<p>Maximum year: ${newHandleYears.calculateMaxYear()}</p>`;
body {padding: 0.5rem 1rem;}
<div id="output"></div>


Solution 1:[1]

You need to add this keyword because you are reassigning value and you don't have to do it in push since its calling same reference and pushing to it.

const output = document.getElementById('output');

function handleYears() {
    let years = [];
    let addYear = function(newYear) {
        years.push(newYear);
    }
    let deleteYear = function(yearToDelete) {
        this.years = years.filter(item => item !== yearToDelete)
    }
    let calculateMaxYear = function() {
        return Math.max(...this.years);
    }

    return {
        years: years,
        addYear: addYear,
        deleteYear: deleteYear,
        calculateMaxYear: calculateMaxYear
    }
}

let newHandleYears = handleYears();

newHandleYears.addYear(2001);
newHandleYears.addYear(1999);
newHandleYears.addYear(2000);
newHandleYears.addYear(2002);

output.innerHTML += `<p>Years: ${newHandleYears.years}</p>`;
output.innerHTML += `<p>Maximum year: ${newHandleYears.calculateMaxYear()}</p>`;
output.innerHTML += `<p>Delete item "${newHandleYears.years[newHandleYears.years.length - 1]}" from "years" array.</p>`;

newHandleYears.deleteYear(2002);

output.innerHTML += `<p>Years: ${newHandleYears.years}</p>`;
output.innerHTML += `<p>Maximum year: ${newHandleYears.calculateMaxYear()}</p>`;
body {padding: 0.5rem 1rem;}
<div id="output"></div>

Solution 2:[2]

After deleting a year, the newHandleYears object is not initialised with the new years value, it holds the old one. You can make another getter for years to get the updated value:

const output = document.getElementById('output');

function handleYears() {
    let years = [];
    let addYear = (newYear) => {
        years.push(newYear);
    }
    let deleteYear = (yearToDelete) => {
        years = years.filter(item => item !== yearToDelete)
    }
    let calculateMaxYear = () => {
        return Math.max(...years);
    }
    let getYears = () => {
        return years
    }

    return {
        getYears: getYears,
        addYear: addYear,
        deleteYear: deleteYear,
        calculateMaxYear: calculateMaxYear
    }
}

let newHandleYears = handleYears();

newHandleYears.addYear(2001);
newHandleYears.addYear(1999);
newHandleYears.addYear(2000);
newHandleYears.addYear(2002);

output.innerHTML += `<p>Years: ${newHandleYears.getYears()}</p>`;
output.innerHTML += `<p>Maximum year: ${newHandleYears.calculateMaxYear()}</p>`;
output.innerHTML += `<p>Delete item "${newHandleYears.getYears()[newHandleYears.getYears().length - 1]}" from "years" array.</p>`;

newHandleYears.deleteYear(2002);

output.innerHTML += `<p>Years: ${newHandleYears.getYears()}</p>`;
output.innerHTML += `<p>Maximum year: ${newHandleYears.calculateMaxYear()}</p>`;
body {padding: 0.5rem 1rem;}
<div id="output"></div>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 miyav miyav
Solution 2 Igor Moraru