Splice within for loop not removing selected indexes

75 Views Asked by At

If page reloaded, splice method returned [0]{'C'} instead of 0:{'B'}

todos = [0:{"title":"A"}, 1:{"title":"B"}, 2:{"title":"C"}] //store todos - localStorage
deletedTodo = [0,2] // remove A & C from todos - store removed element index - localStorage
window.addEventListener("load", (e) => {
  todos = JSON.parse(localStorage.getItem("todos")) || [];
  clearTodo();
});

function for checking deleted indexes that should removed from todos object then return updated todos object otherwise return display Todos()

function clearTodo() {
  if (
    JSON.parse(localStorage.getItem("deletedTodo")) &&
    JSON.parse(localStorage.getItem("deletedTodo")).length > 0
  ) {
    for (
      let index = 0;
      index <= JSON.parse(localStorage.getItem("deletedTodo")).length;
      index++
    ) {
      todos.splice(JSON.parse(localStorage.getItem("deletedTodo"))[index], 1);
    }
    localStorage.setItem("todos", JSON.stringify(todos));

    localStorage.setItem("deletedTodo", JSON.stringify([]));
    deletedIndexex = [];

    return displayTodos();
  } else {
    return displayTodos();
  }
}
3

There are 3 best solutions below

4
mplungjan On BEST ANSWER
  1. Read localStorage once and write in only one place each.
  2. Stay DRY (Don't Repeat Yourself)

For example

const todoObject = JSON.parse(localStorage.getItem("todo") || '{"todos":[], "deletedTodos":[] }')
let deletedTodos = todoObject.deletedTodos;
let todos = todoObject.todos;
const writeLocal = () => localStorage.setItem("todos", JSON.stringify(todoObject));
function clearTodo() {
  if (deletedTodos.length === 0) return; // nothing to do here
  deletedTodos.forEach(index => todos.splice(index, 1));
  todoObject.todos = todos;
  todoObject.deletedTodos = [];
  writeLocal();
  displayTodos();
}
function addTodo(str) {
  todos.push({ "desc":str, "time": new Date().getTime() }); 
  writeLocal();
  displayTodos();
}
5
Alexander Nenashev On

When you splice you should decrease your index by number of deleted items since the array got shorter. To behave your array normally load it from the local storage only once. And since you splice a different array, just filter it:

function clearTodo() {
  const deletedTodos = JSON.parse(localStorage.getItem("deletedTodo"));
  if (deletedTodos?.length) {
    todos = todos.filter((_, i) => !deletedTodos.includes(i));
    localStorage.setItem("todos", JSON.stringify(todos));
    localStorage.setItem("deletedTodo", JSON.stringify([]));
    deletedIndexex = [];
  }
  return displayTodos();

}
0
gachaftcode On

Here's the modified code:

function clearTodo() {
  if (
    JSON.parse(localStorage.getItem("deletedTodo")) &&
    JSON.parse(localStorage.getItem("deletedTodo")).length > 0
  ) {
    const deletedIndexes = JSON.parse(localStorage.getItem("deletedTodo")).sort((a, b) => b - a);
    for (let i = 0; i < deletedIndexes.length; i++) {
      todos.splice(deletedIndexes[i], 1);
    }
    localStorage.setItem("todos", JSON.stringify(todos));
    localStorage.setItem("deletedTodo", JSON.stringify([]));
    return displayTodos();
  } else {
    return displayTodos();
  }
}