javascripthtmllocal-storagedom-manipulation

Displaying localStorage items return [object HTMLLIElement] instead of the li text


Learning here.

My goal is to display the HTML of the li entries that have been saved to local storage. My issue is that when I try to display said li entries, I am only getting back "[object HTMLLIElement]". I have searched everywhere but can't seem to find a solution for my case.

Not sure if I am way off the mark with this one, seen this pattern to be the solution in other questions, but in the for loop at the bottom, I have tried to set item.innerHTML = localStorage.getItem(localStorage.key(i).innerHTML); which in my case does not work.

Any help will be much appreciated as this has given me quite the headache lol

Here is where I am saving the li entries to localStorage:

const savedEntries = [];

saveBtn.addEventListener("click", () => {
  const saveInfo = document.createElement("li");
  saveInfo.innerHTML = `Found: ${foundNumber.innerHTML} | Not Found: ${notFoundNumber.innerHTML} | Archive: ${archiveNumber.innerHTML} | Total: ${totalOfAllNumbers.innerHTML}`;
  saveInfo.classList.add("li");

  const deleteBtn = document.createElement("button");
  deleteBtn.appendChild(document.createTextNode("X"));
  deleteBtn.classList.add("btn");
  deleteBtn.classList.add("li");
  deleteBtn.classList.add("delete-btn");
  saveInfo.appendChild(deleteBtn);
  savedEntries.push(saveInfo);
  console.log(savedEntries);

  savedEntries.forEach((entry, index) => {
    ul.appendChild(entry);
    localStorage.setItem(index, entry);

    deleteBtn.onclick = () => {
      deleteBtn.parentElement.style.display = "none";
      savedEntries.splice(index, 1);
      localStorage.removeItem(index);
      console.log(savedEntries);
    };
  });
});

And Here is where I am attempting to grab them:

window.addEventListener("load", () => {
  if (localStorage.length !== 0) {
    ulDiv.style.display = "block";

    for (let i = 0; i < localStorage.length; i++) {
      let item = document.createElement("li");
      item.innerHTML = localStorage.getItem(localStorage.key(i));
      ul.appendChild(item);
    }
  } else {
    ulDiv.style.display = "none";
  }
});

Solution

  • In JavaScript, the localStorage object is capable of storing data only in the form of strings. If you wish to store any other data types, such as objects, boolean values, or numbers, they will be converted into strings. That's why your list objects are being converted to [object HTMLLIElement]

    In order to achieve what you want:

    1. You need to get the element's code through outerHTML and store it in the localStorage as a string.
    2. Then use insertAdjacentHTML() to append that string to your document.

    For example:

    // getting the code of your li element
    const liCode = document.getElementById("myLi").outerHTML;
    
    // setting the value in the localStorage by converting it to string
    localStorage.setItem("myKey", liCode.toString());
    
    // getting the value from localStorage 
    let li = localStorage.getItem(localStorage.key(i));
    
    // then appending it to your ul element
    let ul = document.getElementById("myUL");
    ul.insertAdjacentHTML("afterend", li);
    

    Please Note:

    The insertAdjacentHTML() method of the Element interface parses the specified text as HTML or XML and inserts the resulting nodes into the DOM tree at a specified position.

    ...

    When inserting HTML into a page by using insertAdjacentHTML(), be careful not to use user input that hasn't been escaped. You should not use insertAdjacentHTML() when inserting plain text.

    Instead, use the Node.textContent property or the Element.insertAdjacentText() method. This doesn't interpret the passed content as HTML, but instead inserts it as raw text.

    Source: MDN docs