title: How do I store a simple cart using localStorage?
body: <p>I'm trying to create a javascript cart for a prototype project I'm working on. I realise that in this situation an MVC framework like Angular/Knockout etc would be absolute perfect but I'm still learning how to use those so I can't use them for this particular project. I also realise I could maintain the cart server-side but that's not an option in this scenario.</p>
  
  <p>At the moment I have a list of html products like so:</p>
  
  <pre><code>&lt;ul id="products"&gt;
    &lt;li data-id="1" data-name="Product 1" data-price="10.00"&gt;
      &lt;input type="text" /&gt;&lt;br /&gt;
      &lt;button&gt;Add to cart&lt;/button&gt;
    &lt;/li&gt;
    &lt;li data-id="2" data-name="Product 2" data-price="15.00"&gt;
      &lt;input type="text" /&gt;&lt;br /&gt;
      &lt;button&gt;Add to cart&lt;/button&gt;
    &lt;/li&gt;
    &lt;li data-id="3" data-name="Product 3" data-price="20.00"&gt;
      &lt;input type="text" /&gt;&lt;br /&gt;
      &lt;button&gt;Add to cart&lt;/button&gt;
    &lt;/li&gt;
  &lt;/ul&gt;
  </code></pre>
  
  <p>On page load I create an empty 'cart' object in localStorage like so:</p>
  
  <pre><code>var cart = {};
  cart.products = [];
  
  localStorage.setItem('cart', JSON.stringify(cart));
  </code></pre>
  
  <p>I've then bound to the click event of the button element as so:</p>
  
  <pre><code>$('button').on('click', function(e) {
      var product = $(this).parent();
  
      var quantity = $(product).find('input[type=text]').val();
  
      // Ensure a valid quantity has been entered
      if (!isValidInteger(quantity) === true) {
          alert('Please enter a valid quantity');
          return;
      }
  
      product.id = $(product).attr('data-id');
      product.name = $(product).attr('data-name');
      product.price = $(product).attr('data-price');
      product.quantity = quantity;
  
      addToCart(product);
  });
  </code></pre>
  
  <p>I've then written an addToCart() function that should take this product and try to push it into the 'products' array that's a property of 'cart':</p>
  
  <pre><code>function addToCart(product) {
      // Retrieve the cart object from local storage
      if (localStorage &amp;&amp; localStorage.getItem('cart')) {
          var cart = JSON.parse(localStorage.getItem('cart'));            
  
          cart.products.push(product);
  
          localStorage.setItem('cart', JSON.stringify(cart));
      } 
  }
  </code></pre>
  
  <p>This isn't working and I'm getting an error: </p>
  
  <pre><code>Uncaught TypeError: Converting circular structure to JSON
  </code></pre>
  
  <p>I don't understand where I'm going wrong, is anyone able to help?</p>
  
  <p>Also once this is resolved, I'm a little confused as to how I'm to maintain the state of the cart. I was hoping I could store all the data in the 'cart' object in localStorage by storing the product ids, names, prices and quantities and then reflecting this in a 'cart' div within the html. If items are added/removed, I'll update the 'cart' object in local storage and then reflect the changes within the html.</p>
  
  <p>Is there a simpler way to do this? I could really use some pointing in the right direction.</p>
  
  <p>Once again I realise that using Angular or even maintaining the state server-side would be an optimal solution but for this project I'm only able to use jquery/javascript so I need to work within my boundaries.</p>
  
  <p>Thanks!</p>