Removing a single todo item

For now, you can only add things to the todo list, but it would certainly be better to be able to remove tasks once they've been completed.

In todo-it.ts, replace the following li.innerText = item; line with li.innerHTML = <a href='#' onclick='removeTodoListItem("${item}")'>${item}</a>;.

With this, we simply generate dummy HTML links that we use to highlight the fact that we can click on each of the items in the todo list. With the onclick event, we simply call a removeTodoListItem function, passing it the item to remove.

Again, using template strings allows us to write more readable code.

Let's implement that function now:

function removeTodoListItem(itemToRemove: string): void { 
    console.log("item to remove: ",itemToRemove); 

    todoList = todoList.filter((value: string, _index, _array) =>{ 
        if(value === itemToRemove) { 
            return false; 
        } 
        return true; 
    }); 
    // unsafe alternative: todoList.splice(...​) 

    // update the todo list 
    updateTodoList(); 

    // apply the todo list filter 
    filterTodoList(); 
} 

For this to compile, you'll need to modify the todoList declaration to switch it from const to let. This is because we need to reassign the object when we filter it.

As you can see in the preceding code snippet, we are using the filter method on the array to create a new one excluding the value we wish to remove. We heavily recommend this approach as it is much safer to create a brand new array than to mutate an existing one.

This might feel counterintuitive if you have an object-oriented background, where mutation is the norm, but, as you'll see with experience, immutability truly helps to avoid surprises and side effects from your code, and is a core functional programming principle.

The main (unsafe) alternative to using filter is to use splice (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice) instead, but, as we mentioned, it really is unsafe. Basically, splice is also slower, creates garbage and is error-prone. More than enough reasons to simply forget about it!

Another even more dangerous alternative is to use delete to remove items from the array. Again that is a mutation, hence is not recommended. In addition, it'll just poke holes in the array, which you simply don't want to have.

By creating a new array instead of mutating the existing one, we could very easily implement an undo functionality! This is how patterns/tools such as Redux work. We won't be able to dive into Redux in this book, but it is definitely something to take a look at https://redux.js.org.

Check out this great article to learn about common pitfalls when working with arrays in JavaScript: https://www.thecodeship.com/web-development/common-pitfalls-when-working-with-javascript-arrays.

In the lambda declaration for the filter, we have used _index and _array as variable names to indicate that we don't care about some of the parameters. Prefixing a parameter name with an underscore is a TypeScript coding convention (also seen in languages such as Kotlin). If we had used another name, then the compiler would've complained about the presence of unused variables in our code. Alternatively, in this case, you could also remove those parameters and TypeScript wouldn't mind. Check out this issue to learn more: https://github.com/Microsoft/TypeScript/issues/9458.

You can find the full list of possible TypeScript compiler errors here: https://github.com/microsoft/TypeScript/blob/v3.4.1/src/compiler/diagnosticMessages.json. Just adapt the version number to see those of newer releases. There is also an excellent write-up of the errors that you will most commonly encounter: https://www.sitepen.com/blog/2017/11/01/common-typescript-error-messages.