DEV Community

Cover image for daily code 78 | js local storage
Gregor Schafroth
Gregor Schafroth

Posted on

daily code 78 | js local storage

alright its time for another small coding exercise! today let’s practice local storage in javascript with a simple to-do list app.

Task

Use JavaScript to create a basic to-do list application that allows users to add, remove, and persist their tasks using localStorage.

Inputs

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Local Storage Exercise</title>
  </head>
  <body>
    <h1>To-Do List</h1>
    <input type="text" id="taskInput" placeholder="Add a new task" />
    <button id="addTaskBtn">Add Task</button>
    <ul id="taskList" class="task-list"></ul>

    <script src="index.js"></script>
  </body>
</html>

Enter fullscreen mode Exit fullscreen mode

that’s all you get. build out the javascript from here! you can find the solution below

Step by Step Solution

were you able to make it?

below you can find the step by step solution with the full one at the end

First, lets implement adding new tasks directly to the DOM

document.addEventListener("DOMContentLoaded",
  (event) => {
    const taskInput = document.getElementById("taskInput");
    const addTaskBtn = document.getElementById("addTaskBtn");
    const taskList = document.getElementById("taskList");

    // extract task input value
    const addTask = () => {
      const task = taskInput.value.trim();
      if (task) {
        addTaskToDOM(task);
        taskInput.value = '';
      }
    };

    // add tasks to DOM
    const addTaskToDOM = (task) => {
      const li = document.createElement("li");
      li.className = "task-item";
      li.textContent = task;

      taskList.appendChild(li);
    }; 

    // Event listener for the add task button
    addTaskBtn.addEventListener("click", addTask);
  });

Enter fullscreen mode Exit fullscreen mode

next let’s add the remove notes feature as well. For this we change the addTaskToDOM function to add a Remove button and then implement the removeTask function

// add tasks to DOM
  const addTaskToDOM = (task) => {
    const li = document.createElement("li");
    li.className = "task-item";
    li.textContent = task;

    const removeBtn = document.createElement("button");
    removeBtn.textContent = "Remove";
    removeBtn.onclick = () => removeTask(li);

    li.appendChild(removeBtn);
    taskList.appendChild(li);
  };

  // Remove task from DOM
  const removeTask = (element) => {
    element.remove();
  };

Enter fullscreen mode Exit fullscreen mode

Ok that works but if we reload the page, our tasks will go all away. To prevent this let’s add them to local storage.

To do that let’s first add 3 lines to our addTask function to the following:

// Add task to localStorage
  const addTask = () => {
      const task = taskInput.value.trim();
      if (task) {
          addTaskToDOM(task);
          let tasks = JSON.parse(localStorage.getItem('tasks')) || []; // new
          tasks.push(task); // new
          localStorage.setItem('tasks', JSON.stringify(tasks)); // new
          taskInput.value = '';
      }
  };
Enter fullscreen mode Exit fullscreen mode

And then for this to make any difference, let’s also load those tasks when the page loads. The actual function call for this needs to be placed after the addTaskToDOM function, so best just to place it at the very end.

// load tasks from localStorage
const loadTasks = () => {
    const tasks = JSON.parse(localStorage.getItem('tasks')) || [];
    tasks.forEach(task => addTaskToDOM(task));
  };

// Load tasks when page loads
  loadTasks();
Enter fullscreen mode Exit fullscreen mode

Alright great, so far this works, but now when we remove items and we reload the page again they come back.

To fix that lets update the the removeTask function

const removeTask = (task, element) => {
      let tasks = JSON.parse(localStorage.getItem('tasks')) || [];
      tasks = tasks.filter(t => t !== task);
      localStorage.setItem('tasks', JSON.stringify(tasks));
      element.remove();
  };
Enter fullscreen mode Exit fullscreen mode

Now removeTask takes an additional parameter, so let’s also fix that when we create the removeBtn

    removeBtn.onclick = () => removeTask(task, li);
Enter fullscreen mode Exit fullscreen mode

And with that we are done! Below you can find the full solution

Full Solution

document.addEventListener('DOMContentLoaded', (event) => {
  const taskInput = document.getElementById('taskInput');
  const addTaskBtn = document.getElementById('addTaskBtn');
  const taskList = document.getElementById('taskList');

  // Load tasks from localStorage
  const loadTasks = () => {
      const tasks = JSON.parse(localStorage.getItem('tasks')) || [];
      tasks.forEach(task => addTaskToDOM(task));
  };

  // Add task to DOM
  const addTaskToDOM = (task) => {
      const li = document.createElement('li');
      li.className = 'task-item';
      li.textContent = task;

      const removeBtn = document.createElement('button');
      removeBtn.textContent = 'Remove';
      removeBtn.onclick = () => removeTask(task, li);

      li.appendChild(removeBtn);
      taskList.appendChild(li);
  };

  // Add task to localStorage
  const addTask = () => {
      const task = taskInput.value.trim();
      if (task) {
          addTaskToDOM(task);
          let tasks = JSON.parse(localStorage.getItem('tasks')) || [];
          tasks.push(task);
          localStorage.setItem('tasks', JSON.stringify(tasks));
          taskInput.value = '';
      }
  };

  // Remove task from localStorage and DOM
  const removeTask = (task, element) => {
      let tasks = JSON.parse(localStorage.getItem('tasks')) || [];
      tasks = tasks.filter(t => t !== task);
      localStorage.setItem('tasks', JSON.stringify(tasks));
      element.remove();
  };

  // Event listener for the add task button
  addTaskBtn.addEventListener('click', addTask);

  // Load tasks when the page loads
  loadTasks();
});
Enter fullscreen mode Exit fullscreen mode

this could of course be improved with styling and other features, but since we are practicing local storage here those don’t really matter.

happy coding everyon!

👋

Top comments (0)