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>

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);
  });

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();
  };

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 = '';
      }
  };

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();

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();
  };

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

    removeBtn.onclick = () => removeTask(task, li);

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();
});

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!

👋

0
Subscribe to my newsletter

Read articles from Gregor Schafroth directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Gregor Schafroth
Gregor Schafroth

Entrepreneur & Junior Programmer, currently learning how to build an OpenAI Assistant's API Chat-bot app with Python, Flask, Heroku, Celery, Redis, etc.