0

i have an array named todoList, all of my data is in it. i saved them to localstorage like this: https://codepen.io/arashkazerouni/pen/YzLxdoQ

const saveToLocal = (array) => {
  window.localStorage.setItem("todo", JSON.stringify(array));
};

todoList = JSON.parse(window.localStorage.getItem("todo"));

i used this saveToLocal function after any change in todoList, and it works. the only problem is when i refresh the page, all items gone. but if i add new todo, all of them will shown again

and there is page script :

const input = document.querySelector("input");
const button = document.querySelector("button");
const todos = document.querySelector(".todos");
const alertRed = document.querySelector(".alert-red");

let todoList = [];
const saveToLocal = (array) => {
  window.localStorage.setItem("todo", JSON.stringify(array));
};

todoList = JSON.parse(window.localStorage.getItem("todo"));
const addToDOM = () => {
  // todos.innerHTML = "";
  for (let i = 0; i < todoList.length; i++) {
    const html = `
    <div class="todo" id=${i}>
    <p class="todo-text" >${todoList[i]}</p>
    <i class="fa-solid fa-check" ></i>
    <i class="fa-solid fa-trash"></i>
    </div>
    `;
    todos.insertAdjacentHTML("beforeend", html);
  }
};
// Add items to list
button.onclick = (e) => {
  e.preventDefault();
  // todos.innerHTML = "";
  if (!todoList.includes(input.value) && input.value !== "") {
    todoList.push(input.value);
    saveToLocal(todoList);
  }
  // console.log(todoList);
  addToDOM();
  input.value = "";
};
// Handle Enter Press
document.onkeypress = (e) => {
  if (e.key === "Enter") {
    button.click();
  }
};
todos.onclick = (e) => {
  e.preventDefault();
  const isCheck = e.target.classList.contains("fa-check");
  const isTrash = e.target.classList.contains("fa-trash");
  if (isCheck) e.target.previousElementSibling.classList.toggle("checked");
  if (isTrash) {
    const element = e.target.parentElement;
    const elementID = parseInt(element.id);
    element.classList.add("removed");
    todoList = todoList.filter((element) => element !== todoList[elementID]);
    saveToLocal(todoList);
    setTimeout(() => {
      addToDOM();
    }, 300);
  }
};

  • you can make sure that you dont call it anywhere with empty array? can you please show me your page's script – islemdev Sep 22 '22 at 05:52
  • `saveToLocal` function seems to be all good. However, why don't you initialize `todoList` with `const` or `let` ? Because this lines also look to be good, but the fact that you don't use any of those let us thing you are doing manipulation on it before, and this seems to be from where your problem come from. Please share a reproduction or more code as @islemdev asked – Dimitri Kopriwa Sep 22 '22 at 05:54
  • @ArashKazerooni it would be way easier and faster if you could share the reproduction on www.codesandbox.io – Dimitri Kopriwa Sep 22 '22 at 05:55
  • @DimitriKopriwa yes sir i'll add it here as soon – Arash Kazerooni Sep 22 '22 at 06:00
  • please after this link todoList = JSON.parse(window.localStorage.getItem("todo")); add console.log(todoList) fill some todo to list then refresh and show me what is in console – islemdev Sep 22 '22 at 06:02
  • 1
    `addToDOM` is your render function, that puts whatever is in the `todoList` array to the screen. So call it immediately when the page is loaded! – FZs Sep 22 '22 at 06:17
  • (Other things: 1. You can just do `let todoList = JSON.parse(localStorage.get("todo"))`, no need to declare and reassign it separately. 2. You should initialize it in case the local storage is empty: `const todoList = JSON.parse(localStorage.get("todo") || "[]")`. 3. Uncomment the `todos.innerHTML = ""` line. 4. Note that setting the HTML content of an element from untrusted input can be a security vulnerability. 5. Checking todos won't persist, you have to store that in the `todoList` array somehow.) – FZs Sep 22 '22 at 06:32
  • i added just window.onload = addToDom() in the end of my code and everything is fixed! :) thanks to everyone for hints and answers – Arash Kazerooni Sep 22 '22 at 06:42
  • `window.onload = addToDom()` is actually not the correct way to do it - the reason is the same as [here](https://stackoverflow.com/q/7137401/8376184). But in this case it's fine to simply do `addToDOM()` on the top level of code. – FZs Sep 22 '22 at 07:04
  • @FZs Checking todos won't persist, you have to store that in the todoList array somehow.) – How can i do this? – Arash Kazerooni Sep 22 '22 at 09:06
  • Instead of storing an array of strings as `todoList` you could make it an array of objects (having like `name` and `checked` as properties), and change `addToDOM` to also conditionally output `checked` classes. – FZs Sep 22 '22 at 12:14

0 Answers0