Capax Capax - 1 month ago 8
Javascript Question

Function stops working after retrieving localStorage

I'm using localStorage on two lists, fruit-shelf & fruit-basket.

If you click on a fruit from fruit-shelf, it appends it to the fruit-basket, and if you refresh the page it's still there — so it remembers everything as it should.

Problem is: if you add one fruit, and then refresh page, you can't add more fruits, the program completely stops working.

I've added a Clear Local Storage button, which works. If you click on it and refresh page, you can add fruits again. But as soon as one fruit is added and you refresh page, you can't add more items to the fruit-basket.

I'm not sure how to put a name on the problem so it's hard to search for solutions (I've tried!).

Can someone point me in the right direction? :-)

Fiddle (I couldn't use SO Snippet here because of localStorage):
https://jsfiddle.net/nrv269hc/7/

JS:

(function() {

var btnClearStorage = document.querySelector('.btn-delete-all');
var fruitShelf = document.querySelector('.fruit-shelf');
var fruitShelfItems = document.querySelectorAll('.fruit-shelf li');
var fruitBasket = document.querySelector('.fruit-basket');

// Store current state of fruitSheflf & fruitBasket
function storestate() {
localStorage.fruitShelf = fruitShelf.innerHTML;
localStorage.currentFruitBasket = fruitBasket.innerHTML;
};

function retrievestate() {

// Retrieve fruits left from shelf
if (localStorage.fruitShelf) {
fruitShelf.innerHTML = localStorage.fruitShelf;
}
// Retrieve stored fruits
if (localStorage.currentFruitBasket) {
fruitBasket.innerHTML = localStorage.currentFruitBasket;
}
};

retrievestate();

for (var i = 0; i < fruitShelfItems.length; i++) {

fruitShelfItems[i].addEventListener('click', function(event) {

fruitBasket.appendChild(this);
storestate();
});

}

// Clear Local Storage
btnClearStorage.addEventListener('click', function() {

localStorage.clear(fruitShelf);
localStorage.clear(fruitBasket);

});

})();

Answer

You need to update the fruitShelfItems as the HTML is update after retrievestate.

Look at updated JsFiddle

(function() {

  var btnClearStorage = document.querySelector('.btn-delete-all');
  var fruitShelf = document.querySelector('.fruit-shelf');
  var fruitShelfItems = document.querySelectorAll('.fruit-shelf li');
  var fruitBasket = document.querySelector('.fruit-basket');

  // Store current state of fruitSheflf & fruitBasket
  function storestate() {
    localStorage.fruitShelf = fruitShelf.innerHTML;
    localStorage.currentFruitBasket = fruitBasket.innerHTML;
  };

  function retrievestate() {

    // Retrieve fruits left from shelf
    if (localStorage.fruitShelf) {
      fruitShelf.innerHTML = localStorage.fruitShelf;
    }
    // Retrieve fruit basket
    if (localStorage.currentFruitBasket) {
      fruitBasket.innerHTML = localStorage.currentFruitBasket;
    }
    // you need to update the fruitShelfItems as the HTML is update after retrievestate
    fruitShelfItems = document.querySelectorAll('.fruit-shelf li');
  };

  retrievestate();

  for (var i = 0; i < fruitShelfItems.length; i++) {

    fruitShelfItems[i].addEventListener('click', function(event) {

      fruitBasket.appendChild(this);
      storestate();
    });

  }

  // Clear Local Storage
  btnClearStorage.addEventListener('click', function() {

    localStorage.clear(fruitShelf);
    localStorage.clear(fruitBasket);

  });

})();