I've made a very basic, bare bones todo list. When I add to the list through the input (wash dishes) it comes out as wash dishes. but on refresh when accessing the object in the array from local storage I get back {"TODO_ITEM:1":"wash dishes"}. My main question is where did I mess up and how do I go about fixing it. I'm assuming its a mess up in how I'm accessing the data. everything I look up and find on accessing the value of an object either doesn't work, says its not a function or comes back as [object object]. this is probably my fifth project in coding as a first timer, any and all advice helps!
//Select everything
const list = document.querySelector('#todo-list');
const form = document.querySelector('#create-todo');
const input = document.querySelector('#new-todo');
let todoCount = 1;
let obj = {};
let todo = [];
// let data = localStorage.getItem('')
//Remove button to remove li
list.addEventListener('click', function(e) {
if (e.target.tagName === 'LI') {
e.target.classList.toggle('done');
} else if (e.target.tagName === 'BUTTON') {
e.target.parentElement.remove();
}
})
// creating a new todo
form.addEventListener('submit', function(e) {
//preventing refresh
e.preventDefault();
//adding array to local storage
addToLocalStorage(todo)
//creating and adding new li w/button to list
createLi()
console.log(localStorage)
})
//accessing local storage
function getFromLocalStorage() {
const reference = localStorage.getItem('TODO_LIST')
if (reference) {
todo = JSON.parse(reference)
renderTodo(todo)
}
}
//new Li function
function createLi() {
const newLi = document.createElement('li');
const newBtn = document.createElement('button');
newLi.innerText = input.value;
list.append(newLi);
newBtn.innerText = 'Remove';
newLi.append(newBtn);
input.value = '';
}
//add to local storage function
function addToLocalStorage(todo) {
let obj = {}
let key = 'TODO_ITEM:' + todoCount
console.log(obj)
todoCount++
obj[key] = input.value
todo.push(obj)
localStorage.setItem('TODO_LIST', JSON.stringify(todo))
}
// keep todo list on refresh function
function renderTodo() {
list.innerHTML = '';
for (let i = 0; i < todo.length; i++) {
console.log(todo[i])
let indx = todo[i]
const newLi = document.createElement('li');
const newBtn = document.createElement('button');
newLi.innerText = JSON.stringify(indx);
list.append(newLi);
console.log()
newBtn.innerText = 'Remove';
newLi.append(newBtn);
console.log(indx)
}
}
getFromLocalStorage();
Current Version
The issue is that the todos are saved to localstorage
as js objects with the format:
// { key: value }
{"TODO_ITEM:1": "Todo value"}
So when you later extract it, you need to access the value of the object that holds the todo text:
function getFromLocalStorage() {
// this returns a list of todos in the above format
const reference = localStorage.getItem('TODO_LIST');
if (reference) {
const todoItems = JSON.parse(reference);
// loop over the todos array and get individual todos
todoList = todoItems.map((item) => {
// use Object.values to get the 'Todo value' from the object {"TODO_ITEM:1": "Todo value"}
const todoValue = Object.values(item)[0];
return todoValue;
});
todo = todoList;
renderTodo(todo);
}
}
Then later in your renderTodos
function, don't stringify the value:
// Remove this
newLi.innerText = JSON.stringify(indx);
// add this
newLi.innerText = indx;
You can learn more about Object.keys()
here, and array.map()
here.
Better Version
This process could have been a lot easier if you considered storing just a list of todo text as ['wash dishes', 'have some coffee']
etc. Adding the todo's as objects just complicates the logic given it is just a simple todo app.
Therefore I suggest you implement something like this:
addToLocalStorage
function:
function addToLocalStorage(todo) {
todo.push(input.value);
localStorage.setItem('TODO_LIST', JSON.stringify(todo));
}
getFromLocalStorage
function:
function getFromLocalStorage() {
// this returns a stringified array of todos
const reference = localStorage.getItem('TODO_LIST');
if (reference) {
todos = JSON.parse(reference);
renderTodo();
}
}
Hope it helps.