26

I'm trying to make shopping cart front end with localstorage, as there are some modal windows and I need to pass cart items info there. Every time you click add to cart it should create object and it to localstorage. I know I need to put everything in array and push new object to array, after trying multiple solutions - can't get it to work

That's what I have (saves only last object):

var itemContainer = $(el).parents('div.item-container');
var itemObject = {
    'product-name': itemContainer.find('h2.product-name a').text(),
    'product-image': itemContainer.find('div.product-image img').attr('src'),
    'product-price': itemContainer.find('span.product-price').text()
};

localStorage.setItem('itemStored', JSON.stringify(itemObject));
alexndm
  • 2,899
  • 5
  • 24
  • 25
  • 1
    ItemObject not itemObject? Your variable names are wrong. Javascript is case-sensitive. – tafoo85 Aug 28 '12 at 15:42
  • The i is lower case in the object your saving to `localStorage` while the object your creating has an upper case I. – Jack Aug 28 '12 at 15:42
  • sorry I just typed it here incorrectly, fixed now – alexndm Aug 28 '12 at 15:43
  • You mention that you know that you need to add the objects to an `array`, but your code snippet doesn't show that, did you get an error or are you asking how to do that? – Jack Aug 28 '12 at 15:46
  • may be this link will helpful http://stackoverflow.com/questions/23554456/how-do-i-store-a-simple-cart-using-localstorage/37169851#37169851 – Musa May 11 '16 at 17:50

2 Answers2

53

You're overwriting the other objects every time, you need to use an array to hold them all:

var oldItems = JSON.parse(localStorage.getItem('itemsArray')) || [];

var newItem = {
    'product-name': itemContainer.find('h2.product-name a').text(),
    'product-image': itemContainer.find('div.product-image img').attr('src'),
    'product-price': itemContainer.find('span.product-price').text()
};

oldItems.push(newItem);

localStorage.setItem('itemsArray', JSON.stringify(oldItems));

http://jsfiddle.net/JLBaA/1/

You may also want to consider using an object instead of an array and use the product name as the key. This will prevent duplicate entries showing up in localStorage.

Hunter
  • 3,080
  • 20
  • 23
jbabey
  • 45,965
  • 12
  • 71
  • 94
  • Using it for a project, working like a charm! exactly what I need, as for the duplicate entries I found a way that would solve this problem: you can check the current array if it has this element inside of it using the .some() function, if true then use a forEach() and check if the current object is equal to the one you want to add, in my case increasing the quantity of this order by the new quantity – technolaaji Jun 14 '19 at 11:04
0

it's not directly related to local storage but nowdays, it's a good practice to use React/Angular. here is a example:

var TodoItem = React.createClass({
  done: function() {
    this.props.done(this.props.todo);
  },

  render: function() {
    return <li onClick={this.done}>{this.props.todo}</li>
  }
});

var TodoList = React.createClass({
  getInitialState: function() {
    return {
      todos: this.props.todos
    };
  },

  add: function() {
    var todos = this.props.todos;
    todos.push(React.findDOMNode(this.refs.myInput).value);
    React.findDOMNode(this.refs.myInput).value = "";
    localStorage.setItem('todos', JSON.stringify(todos));
    this.setState({ todos: todos });
  },

  done: function(todo) {
    var todos = this.props.todos;
    todos.splice(todos.indexOf(todo), 1);
    localStorage.setItem('todos', JSON.stringify(todos));
    this.setState({ todos: todos });
  },

  render: function() {
    return (
      <div>
        <h1>Todos: {this.props.todos.length}</h1>
        <ul>
        {
          this.state.todos.map(function(todo) {
            return <TodoItem todo={todo} done={this.done} />
          }.bind(this))
        }
        </ul>
        <input type="text" ref="myInput" />
        <button onClick={this.add}>Add</button>
      </div>
    );
  }
});

var todos = JSON.parse(localStorage.getItem('todos')) || [];

React.render(
    <TodoList todos={todos} />,
    document.getElementById('container')
);

from here

ChaosPredictor
  • 3,777
  • 1
  • 36
  • 46