I am using javascript to populate the HTML inside my todo list, but I am struggling to implement a way of storing the data inbetween refreshes of the webpage. I know I should be using localStorage get/set but I’m unsure how best to implement, any guidance would be much appreciated.
I’ve tried implementing myself but I believe I am making errors in the placement of my functions and keep getting either HTML duplications or app breakage
const submitButton = document.querySelector(".submit-button");
const taskInput = document.querySelector(".todo-input");
const listInput = document.querySelector(".list-input");
const checkboxDelete = document.querySelectorAll(".checkbox");
const deleteButton = document.querySelector(".delete-tasks");
let todoList = JSON.parse(localStorage.getItem("todoList")) || [];
submitButton.addEventListener("click", () => {
const checkIfhidden = document.querySelector(".todo-list");
const deleteButton = document.querySelector(".delete-tasks");
if (taskInput.value === "") {
window.alert("Please enter a new task before submitting");
} else {
addTodo(taskInput.value);
deleteButton.classList.remove("hidden");
if (checkIfhidden.classList.contains("hidden")) {
checkIfhidden.classList.remove("hidden");
}
}
});
function addTodo(item) {
if (item !== "") {
const todo = {
id: Date.now(),
name: item,
completed: false,
};
todoList.push(todo);
renderTodoList(todo);
taskInput.value = "";
}
}
function renderTodoList() {
const renderedList = document.querySelector(".todo-list");
renderedList.innerHTML = "";
todoList.forEach((todo) => {
const newListItem = document.createElement("div");
newListItem.classList.add("list-item");
newListItem.innerHTML = `
<label for="item-${todo.id}">${todo.name}</label>
<input type="checkbox" class="checkbox" data-delete-id="${todo.id}">`;
renderedList.appendChild(newListItem);
});
saveToStorage();
}
deleteButton.addEventListener("click", () => {
const checkboxes = document.querySelectorAll(".checkbox:checked");
checkboxes.forEach((checkbox) => {
const todoId = parseInt(checkbox.getAttribute("data-delete-id"));
todoList = todoList.filter((todo) => todo.id !== todoId);
});
if (todoList.length < 1) {
document.querySelector(".todo-list").classList.add("hidden");
document.querySelector(".delete-tasks").classList.add("hidden");
}
renderTodoList();
});
function saveToStorage() {
localStorage.setItem("todoList", JSON.stringify(todoList));
}
<script src="https://kit.fontawesome.com/bd47ea96a8.js" crossorigin="anonymous"></script>
<div class="card">
<div class="title">
<h3>To-Do List</h1>
<i class="fa-solid fa-list-check"></i>
</div>
<div class="list-input">
<input type="text" class="todo-input
" placeholder="Add your task">
<button class="submit-button">Add</button>
</div>
<div class="todo-list hidden">
</div>
<button class="delete-tasks hidden">Mark as Complete</button>
</div>
<script type="module" src="./todo.js"></script>
3
Answers
Please do mention what code you tried, and what errors you received.
However, using
localStorage
is pretty easy. Since your variabletodoList
is an array of objects, you’ll also have to usestringify
andparse
functions provided in JSON.For storing – use
JSON.stringify(object)
to convert yourtodoList
variable to a string, and then store it in localStorage (since it does not support object storage).For retrieving – use
JSON.parse(string)
to parse the stored string to an object. Also keep a empty array as fallback incase the key ("todoList") is undefined or null.Hope this helps!
I do not see any type of error, however, if you are using js only you should be able to get your local storage like this:
by setting it:
localstorage.setitem("jwt", jwtCurrent);
and by obtaining them:
const value = localStorage.getItem(key);
You save this in the storage of the browser, so you will be able to find it in its section
You can write some wrapper functions to handle serialization and serialization of your data.
You can also add options to hint at the type of data that is being stored or retrieved.
Usage
Here is how you would use the
saveToLocalStorage
andloadFromLocalStorage
functions above:Type inference and decoupling logic
Instead of a bunch of options to determine how to serialize the data, you can use the
typeof
operation to infer the type of the data.You could also decouple the serialization logic to simply the logic and make it more modular.
Keep in mind that this only works if you supply a default value, of the correct type.
Here are the updated functions:
And finally the modified usage: