storing an array of dom elements in local storage does not work. How to fix?

Viewed 40

I'm trying to store an array that holds DOM elemenst into localStorage. I can't append the elements I store in the array when storing/getting it from localStorage. But currently, my program works if I don't use localStorage, and I can append the array elements completely fine. Here's an example I just quickly wrote up which would lead to an error for me when using localStorage. What is the cause for this error?

**html**
<div class = "container">
   <div class = "stuff"> Store this text </div>
</div>

<div class = "storeHere">


**index.js**
let arr = [];
if (localStorage.length == 0) localStorage.setItem("arr", JSON.stringify(arr));
else {
   //psuedocode: Calling the imported method in "other.js"
}

**other.js** 
method() {
   let temp = [];
   temp = JSON.parse(localStorage.getItem("arr"));
   temp.push(document.querySelector(".stuff");
   localStorage.setItem("arr", JSON.stringify(temp));

   const storeHere = document.querySelector(".storeHere");
   
   storeHere.appendChild(temp[0]); //Error, not of type Node



}

3 Answers

Put only serializable values into storage. Elements aren't serializable.

If you want to store Store this text, then store just that text. If the dynamic values include nested elements, either construct those nested elements when needed, or store the whole HTML string and set the .innerHTML of the container.

Here, the child of .stuff is only a plain single string, so just put that one string into storage.

// store string
localStorage.stuffText = document.querySelector('.stuff').textContent;

// retrieve string and put into DOM
if (localStorage.stuffText) {
  document.querySelector('.stuff').textContent = localStorage.stuffText;
  // or if you want to put it into a .storeHere element, use that selector instead
}

If you want to store an array of strings, then maybe something like

const storedArr = localStorage.arr ? JSON.parse(localStorage.arr) : [];
// store string
storedArr.push(document.querySelector('.stuff').textContent);
localStorage.stuffText = JSON.stringify(storedArr);

// retrieve string and put into DOM
if (localStorage.arr) {
  const storedArr = JSON.parse(localStorage.arr);
  for (const item of storedArr) {
    document.querySelector('.stuff').textContent = item;
  }
  // or if you want to put it into a .storeHere element, use that selector instead
}

HTML Element is not serializable, so the localStorage cannot store it. You need to serialize it into string before save it. I recommend using element.outerHTML with JSON.stringify .

Example code in your case with array:

// Serialize
const arr = []
// convert to string
const elementAsString = document.querySelector('div').outerHTML
// add to your current array
arr.push(elementAsString)
// use JSON.stringify to keep correct array format in localStorage
localStorage.setItem('arr', JSON.stringify(arr))


// Deserialize
const saveArr = JSON.parse(localStorage.getItem('arr'))
// we need create an empty element first
const e = document.createElement('div')
// append element to a parent before set outerHTML
document.body.append(e)
// set HTML for it
e.outerHTML = saveArr[0]

You just need to replace these two line and your bugs will fix.

Inside other.js method() function :-

function method () {
 //temp.push(document.querySelector(".stuff"));
 temp.push(document.querySelector(".stuff").outerHTML);

  //storeHere.appendChild(temp[0])
  storeHere.innerHTML += temp[0];
}

Explanation

  1. We cannot stringify a HTMLNode ( which is returned by the document.querySelector) because it is not a string, but we can get it as a string using its outerHTML property.
  2. When you push the HTMLNode in the arr and set it to localStorage as string then localStorage.getItem("arr") return "[ '[object HTMLNode]' ]" as a string which you parsed as an array. It makes temp[0] = '[object HTMLNode]', which is a string ( not the HTMLNode ), which give you the error on appending it as a child Node ( that you mentioned in the comment ).

I was a bit late in answering because something came up when I was typing the answer

Related