Home > Software design >  Updating local storage after delete item
Updating local storage after delete item

Time:10-04

I build my first ToDo App, and its almost done. But i meet some trouble with delete items from list. If i create new task and try delete it, its deleted only from DOM, but if i refresh page i can delete task from local storage and from DOM. Please, explain what i make wrong and how to fix that. Thank you for your attention.

    <div >
    <ul ></ul>
    <form  action="">
        <label  for="task">
            <input  id="task" type="text" placeholder="Enter new task" maxlength="30">
            <input  type="submit" value=" ">
        </label>
    </form>
    </div>

const taskList = document.querySelector(".todo_tasks-wrapper");
const formTodo = document.querySelector(".control");
const inputTask = document.querySelector(".todo_input");

const taskKeeper = [];
let taskIdCounter = -1;

const data = JSON.parse(localStorage.getItem("tasks"));

const updateHtml = (taskObj) => {
    const newLi = document.createElement("li");
    newLi.innerHTML = `<li id="${taskObj.id}" >
        <span>${taskObj.task}</span>
        <button >
            <img src="assets/todo-cancel.png" alt="Cancel">
        </button>
    </li>`;
    taskList.append(newLi);
}

const newTask = (info) => {
    taskIdCounter  = 1;
    const taskObj = {
        task: info,
        id: taskIdCounter,
    };
    taskKeeper.push(taskObj);
    localStorage.setItem("tasks", JSON.stringify(taskKeeper));
    updateHtml(taskObj);
};

formTodo.addEventListener("submit", event => {
    event.preventDefault();
    const info = inputTask.value.trim();
    if(info.length !== 0) {
        newTask(info);
        inputTask.value = "";
        inputTask.focus();
    }
});

taskList.addEventListener("click", (event) => {
    for (let el of event.composedPath()) {
        if (el.matches && el.matches("button.cancel-task")) {
            let uniqueId =  (el.parentNode.getAttribute("id"));
            for (let itemId of data) {
                if(itemId.id === uniqueId) {
                    let getIndex = data.indexOf(itemId);
                    data.splice(getIndex, 1);
                    localStorage.setItem("tasks", JSON.stringify(data));
                }
            }
            el.parentNode.remove();
        }
    }
});

if(data !== null) {
    for (let item of data) {
        updateHtml(item);
    }
}

CodePudding user response:

  • Don't use IDs for your tasks. When deleting an element, you can assign a click handler on creation of your "x" button.
  • Your taskIdCounter is useless since on page refresh you're starting again from 0. Get rid of it. You know now hot to remove Items from a list
  • Don't use a form if you don't need one.
  • Use type="button" on your BUTTONElements

Here's a remake of your code:

<ul id="tasks-list"></ul>
<div>
  <input id="tasks-text" id="task" type="text" placeholder="Enter new task" maxlength="30">
  <button id="tasks-add" type="button"> </button>
</div>

JavaScript

// DOM utility functions:

const el = (sel, par) => (par || document).querySelector(sel);
const els = (sel, par) => (par || document).querySelectorAll(sel);
const elNew = (tag, prop) => Object.assign(document.createElement(tag), prop);


// Tasks:

const elList = el("#tasks-list");
const elText = el("#tasks-text");
const elAdd = el("#tasks-add");

const tasks = JSON.parse(localStorage.tasks ?? "[]");

const taskRemove = (taskObj, elTask) => {
  const idx = tasks.indexOf(taskObj);
  tasks.splice(idx, 1);
  localStorage.tasks = JSON.stringify(tasks);
  elTask && elTask.remove();
};

const taskAdd = (text) => {
  const taskObj = { task: text };
  tasks.push(taskObj);
  localStorage.tasks = JSON.stringify(tasks);
  taskInsert(taskObj);
};

const taskInsert = (taskObj) => {
  const elTask = elNew("li", {
    className: "item-task",
    innerHTML: `<span>${taskObj.task}</span>`
  });
  const elRemove = elNew("button", {
    type: "button",
    innerHTML: "&times;",
    onclick() {
      taskRemove(taskObj, elTask);
    }
  });
  elTask.append(elRemove);
  elList.append(elTask);
};

elAdd.addEventListener("click", () => {
  const info = elText.value.trim();
  if (!info.length) return;
  taskAdd(info);
  elText.value = "";
  elText.focus();
});

// Init
tasks.forEach(taskInsert);

As you can see, to get the index of the task to remove, simply pass the original object reference into const idx = tasks.indexOf(item);

  • Related