0

I'm using local storage as below like

  var post = {
    title: 'abc',
    price: 'USD5'
  };

window.localStorage['book'] = JSON.stringify(post);

I want to create nested json in my localstorage, if above code is within a click event for the user to click save, it will delete the old data and replace it. How to push new value as an array object?

Elton Jamie
  • 586
  • 6
  • 17
  • *"store array into localstorage instead of replace"* That's not an array, that's an object. – T.J. Crowder Mar 21 '15 at 14:15
  • You need to extract from local storage first, then append your changes and re-store – scunliffe Mar 21 '15 at 14:16
  • @T.J.Crowder isn't multiple object people call it array? – Elton Jamie Mar 21 '15 at 14:17
  • @EltonJamie: What's in your question is an object with multiple properties. An array is a different thing: `[1, 2, 3, 4]`, that kind of thing. Arrays have order, for instance, which objects do not. – T.J. Crowder Mar 21 '15 at 14:18
  • @T.J.Crowder but in my localstorage's key, it has [] wrapped between, is [{'1':''a}] an array or object? – Elton Jamie Mar 21 '15 at 14:26
  • @EltonJamie: That's an array with one entry, where the entry is an object. But that's not what you'd get with what's in your question. With what's in your quesiton, you'd get `{"title":"abc","price":"USD5"}` (no `[]`), which is just an object, not an array. – T.J. Crowder Mar 21 '15 at 14:35
  • @T.J.Crowder ok my bad then, it should be array because for me it's more neat to stroe stuff :) – Elton Jamie Mar 21 '15 at 14:47

2 Answers2

3

Use an actual array, e.g. on page load:

var posts = JSON.parse(localStorage['book'] || "[]");

Then as you're working with it, add to the array in memory:

posts.push({
   title: 'abc',
   price: 'USD5'
});

Any time you want to save the value back to local storage:

localStorage['book'] = JSON.stringify(posts);

Here's a complete functional example (live copy; sadly, Stack Snippets disallow local storage):

HTML:

<div>
  <label>
    Name:
    <input type="text" id="txt-name">
  </label>
</div>
<div>
  <label>
    Price:
    <input type="text" id="txt-price">
  </label>
</div>
<div>
  <input type="button" value="Add" id="btn-add">
</div>
<div id="list"></div>

JavaScript (must be after the HTML in the document):

(function() {
  var nameField = document.getElementById("txt-name"),
    priceField = document.getElementById("txt-price");

  // On page load, get the current set or a blank array
  var list = JSON.parse(localStorage.getItem("list") || "[]");

  // Show the entries
  list.forEach(showItem);

  // "Add" button handler
  document.getElementById("btn-add").addEventListener(
    "click",
    function() {
      // Get the name and price
      var item = {
        name: nameField.value,
        price: priceField.value
      };

      // Add to the list
      list.push(item);

      // Display it
      showItem(item);

      // Update local storage
      localStorage.setItem("list", JSON.stringify(list));
    },
    false
  );

  // Function for showing an item
  function showItem(item) {
    var div = document.createElement('div');
    div.innerHTML =
      "Name: " + escapeHTML(item.name) +
      ", price: " + escapeHTML(item.price);
    document.getElementById("list").appendChild(div);
  }

  // Function for escaping HTML in the string
  function escapeHTML(str) {
    return str.replace(/&/g, "&amp;").replace(/</g, "&lt;");
  }
})();

Side note: If there's any chance at all you might have to support your code on older browsers that don't have local storage at some point, you can give yourself the option of using a polyfill that writes to cookies if you use the more verbose .getItem(...)/.setItem(..., ...) API, as they can be polyfilled whereas accessing via [] as in the above can't be.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • @EltonJamie: If you have any further questions related to the above, feel free to ask. – T.J. Crowder Mar 22 '15 at 10:43
  • why you first used add but push later? – Elton Jamie Mar 22 '15 at 12:20
  • @EltonJamie: Er...um...because the first bit was wrong. :-) I don't know *where* that came from! Fixed. – T.J. Crowder Mar 22 '15 at 12:22
  • as I know can't push using an object, so the first line var posts = JSON.parse(localStorage['book'] || "[]"); is an array? json.parse return an array? – Elton Jamie Mar 22 '15 at 12:27
  • 1
    @EltonJamie: `JSON.parse` returns whatever the JSON defines. In this case, because what we store is the JSON version of an array, it returns an array. If there's nothing in localStorage for "book", we use JavaScript's [curiously powerful `||` operator](http://blog.niftysnippets.org/2008/02/javascripts-curiously-powerful-or.html) to use the string `"[]"` if nothing has ever been saved, which parses to an empty array. – T.J. Crowder Mar 22 '15 at 12:32
  • but I have 1 problem more, although I did successfully pushed my items into localstorage, my scope didn't update. I use $state to route, and I do this $scope.savedData = $localstorage.getObject('lyric'); but I need to refresh to see the latest localstorage data. – Elton Jamie Mar 22 '15 at 12:38
  • @EltonJamie: Now *that* would be a separate Angular-related question. Afraid I can't help there. – T.J. Crowder Mar 22 '15 at 13:39
0

localStorage supports strings. You should use JSONs stringify() and parse() methods.

If I understood the question and what you are looking for is storing an array and not just an object with properties.

As scunliffe commented, What you can do in order to add items to an array which is stored in the local storage is: Generating the array with first object:

var array = []; 
array[0] = //Whatever; 
localStorage["array"] = JSON.stringify(array);

Adding items to the array:

//Adding new object 
var storedArray = JSON.parse(localStorage["array"]);
sotreadArray.push(//Whatever); 
localStorage["array"] = JSON.stringify(array);

This way you store an JSON object representing an array.

As mentioned in this post You can also extend the default storage-objects to handle arrays and objects by:

Storage.prototype.setObj = function(key, obj) {
    return this.setItem(key, JSON.stringify(obj))
}
Storage.prototype.getObj = function(key) {
    return JSON.parse(this.getItem(key))
}
Community
  • 1
  • 1
Or Guz
  • 1,018
  • 6
  • 13