1

I am working on a shopping cart application were users can click an Add to Cart button that will then add the specific item to local storage. When the user is adding a product to their shopping cart I need to be able to check to see if that specific item/value/product already exists in local storage. If it does, I need to increase only the count of that item/value/product by 1. If not, I need to add an entirely new item/value/product to local storage with a count of 1.

How can I find if an item already exists in local storage and compare it to the id of the current product that a user is attempting to add to their cart? My first few attempts failed miserably and have yet to find anything online that is helping with this issue. Is there a better way of going about this? Any assistance is appreciated. Even a good link to a good page would be extremely helpful.

Below is the code I have to attempt in checking for if the productid being added matches any of the productids in local storage. Basically if the productId that is being added matches the productId of an item in local storage simply add 1 to the quantity.

var retrieverObject = localStorage.getItem('Products');
var retrieveObject = JSON.parse(retrieverObject);

var data = {};
var productId = currentNode.name;
var product = currentNode;

data.productPrice = product.parentNode.previousSibling.previousSibling.id;
data.productId = productId;

var length = retrieveObject.length;
console.log(length);
for(var i = 0; i<length; i++){
  if(retrieveObject[i].productId == data.productId){
    var quantity = retrieveObject[i].quantity;
        retrieveObject.push({"productPrice": data.productPrice, "productId": data.productId, "quantity": quantity++});
  }else{
        retrieveObject.push({"productPrice": data.productPrice, "productId": data.productId, "quantity": 1});
  }
}
console.log(retrieveObject);

localStorage.setItem('Products', JSON.stringify(retrieveObject));
var retrievedObject = localStorage.getItem('Products');
var obj = JSON.parse(retrieverObject);
var len = obj.length;
console.log(len);

  for(var i=0; i<len;i++){
    console.log(obj[i]['productPrice']+", "+obj[i]['productId']);
  }

} }

There are a few issues. First, I am not entirely certain that the productId of the retrieved object is being compared to the one that is being added. Secondly, the for(var i = 0; i<length; i++){} definitely does not seem to be doing what was expected and is multiplying the number of items being added by 2. Thirdly, which may relate to the second issue, the retrieveObject.push() is not updating the quantity of the product but is adding an entire new entry to local storage. The given answers did not seem to be working for me before so this is what I have been working on. Any new answers or general help would be great.

PT 2. : So I am having an issue with the first entry into the local storage. Without noting that when there is nothing in local storage and you make a call to get the items in it, it returns null or undefined. So currently I have it set up like this:

if(localStorage.getItem("Products") === null || localStorage.getItem("Products") === undefined){
  var data = {};
  var productId = currentNode.name;
  var product = currentNode;

  data.productPrice = product.parentNode.previousSibling.previousSibling.id;
  data.productId = productId;
  var obj = [];
  obj = obj[data.productId] = {
    productPrice: data.productPrice,
    count: 1
  };
  console.log(obj);
  localStorage.setItem('Products', JSON.stringify(obj));
}

else{
  var retrieverObject = localStorage.getItem('Products');
  var retrieveObject = JSON.parse(retrieverObject);

  var data = {};
  var productId = currentNode.name;
  var product = currentNode;

  data.productPrice = product.parentNode.previousSibling.previousSibling.id;
  data.productId = productId;

  if(retrieveObject[data.productId]){
    retrieveObject[data.productId].count++;
  }else{
    retrieveObject[data.productId] = {
      productPrice: data.productPrice,
      count: 1
};
  }
console.log(retrieveObject);
localStorage.setItem('Products', JSON.stringify(retrieveObject));
}

This creates a first entry in local storage that looks like this : {"productPrice":"78.34","count":1}, and then when adding others looks like this: {"productPrice":"78.34","count":1,"rJUg4uiGl":{"productPrice":"78.34","count":3}} and works perfectly fine. The issue is getting the first entry to b formatted properly. When I change the code in the first if statement like so:

var obj = [];
      obj[data.productId] = {
        productPrice: data.productPrice,
        count: 1
      }

I get an empty [] in local storage but when I console.log the obj it is in the proper format. [rJUg4uiGl: Object]. I have been stuck on this and haven't been able to get it working. Again, any help would be really appreciated.

Zgbrell
  • 159
  • 4
  • 17

3 Answers3

1

Once you have your data structure in obj, I would suggest using a dictionary with product IDs as keys.

To add the order or whatever, where you have:

obj.push({"productPrice": data.productPrice, "productId": data.productId});

Use:

if (obj[data.productId]) { // if the entry exists,
  // increment the count
  obj[data.productId].count++;
} else { // if it doesn't,
  // add a new entry with count = 1
  obj[data.productId] = {
    productPrice: data.productPrice,
    count: 1
  };
}

Here is a complete function, including localStorage handling:

function addToCart(productID, productPrice) {
  // get the current cart, or an empty object if null
  var cart = JSON.parse(localStorage.getItem("Products")) || {};

  // update the cart by adding an entry or incrementing an existing one
  if (cart[productId]) {
    cart[productId].count++;
  } else {
    cart[productId] = {
      productPrice, // shorthand for `productPrice: productPrice,`
      count: 1
    };
  }

  // put the result back in localStorage
  localStorage.setItem("Products", JSON.stringify(cart));
}

The solution above is preferable because you can check for a productId without looping through the whole list. If you really want to keep your current data structure of an array of objects, you could update it like this:

var length = retrieveObject.length;
console.log(length);
for (var i = 0; i < length; i++) {
  if (retrieveObject[i].productId == data.productId) {
    retrieveObject[i].quantity++; // update the entry in the array
  } else {
    retrieveObject.push({
      productPrice: data.productPrice,
      productId: data.productId,
      quantity: 1
    });
  }
}

Note that you shouldn't push a new entry into the array; just update the existing one.

qxz
  • 3,814
  • 1
  • 14
  • 29
  • Updated my question if you would like to take another look and continue to help. This option was the best answer that was given but wasn't quite the solution I am looking for – Zgbrell Dec 09 '16 at 00:35
  • I've edited, but a dictionary/map data structure would be more intuitive & efficient for this situation than an array. – qxz Dec 10 '16 at 01:10
  • Giving it more thought it seems to be an easier route to take your recommended method. The idea is that a user is going to add these different products to their "cart". When they then click the 'view cart' link the new page will be loaded with all of the products and their data. Essentially, In order to get all of these items in local storage I would need a for loop that loops through all of the keys in local storage as opposed to looping through all of the objects in the array? – Zgbrell Dec 10 '16 at 03:06
  • Correct; you could use `for ... in` or `Object.keys()` to loop over the product ids. – qxz Dec 10 '16 at 03:17
  • Ok so, when making the first, initial setting of items into local storage the localStorage.getItem breaks due to it returning a null. So I need to be able to add the first add to the local storage in the correct format. Whenever I am able to match the format of: BJ_7VOiGg":{"productPrice":"3000","count":4}, after the initial add is there the function is overwriting this entry completely, regardless of which product is being added. Any idea why that would be happening? It all works perfectly fine when first entry looks like: {"productPrice":"78.34","productId":"rJUg4uiGl" , formatting must be = – Zgbrell Dec 10 '16 at 03:53
  • I can post more code if youre still willing to help. I honestly ran out of room on the last comment :/ haha In the meantime I will certainly let you know if I can solve this issue. Regardless you have already helped answer my question I posted about. Really appreciate all your assistance! – Zgbrell Dec 10 '16 at 03:57
  • Glad to help. If you edit your question with the code you currently have, I'll take a look – qxz Dec 10 '16 at 21:21
  • I added a PT 2 to my question. Any assistance again would be extremely appreciated. – Zgbrell Dec 10 '16 at 21:37
  • I've edited again. The key is to just use `||` to make `null` default to an empty object. See [this question](http://stackoverflow.com/questions/2100758/javascript-or-variable-assignment-explanation) (You could also use an if `===null` statement if you're more comfortable with that.) – qxz Dec 10 '16 at 23:07
  • Wow ok, the function that you supplied works out fantastically to store this information in local storage.The only thing I had to adjust was the productPrice portion because it neeeded to store data.productPrice instead of just productPrice. Now the next portion is being able to loop through all the objects stores within local storage. I plan to work on this tonight a little bit and tomorrow morning. If I am having any issues I will probably continue to ask for you assistance. Regardless you deserve some more ++++++++ for you help so thank you so much. – Zgbrell Dec 11 '16 at 02:20
  • I just now need to find the best way to loop through all the objects that are stored within that specific key of 'Products'. I was working on this a bit earlier and it was causing a little bit of some issues but im hoping with some more trial and error, and maybe a good nights rest will help solve the issue. If youre up and willing to maybe push me in the right direction I would not complain :) Again, Thank you so much for your help. Definitely have already helped/made understanding local storage and how storing objects in it much more understandable for me! – Zgbrell Dec 11 '16 at 02:22
  • [link](http://stackoverflow.com/questions/41089118/how-to-make-a-successful-ajax-request-using-javascript-on-page-load) @qxz will you take a look at this one? So many issues I have been getting stuck on :( – Zgbrell Dec 11 '16 at 17:46
  • [link](http://stackoverflow.com/questions/41091862/how-to-properly-use-a-for-loop-inside-of-a-while-loop-in-nodejs) Yet another issue if you're bored and would like to continue to help me with my continual struggles with local storage and handling that data. @qxz – Zgbrell Dec 11 '16 at 22:31
0

Assuming you are using localStorage node package you could do

if (localStorage.getItem('Products') !== null) {
   localStorage.setItem('Products', JSON.stringify(obj));
}

Here is your reference:

https://www.npmjs.com/package/localStorage

Regards

Update:

Searching within your objet is a different story... so you want to check if the Product id is there then you can search for it using lodash

var _ = require('lodash');
// the rest of your code to get the data.productId set

if (localStorage.getItem('Products') !== null) {
   var arrayOfProducts = localStorage.getItem('Products');
   var existingProducts = _.filter(arrayOfProducts, function (product) { return product.productId === data.productId });
   if (existingProducts.length > 0) {
      // product found, do your logic
   }
}

Here's lodash info https://www.npmjs.com/package/lodash

The other option is using a dictionary and having the productId as key and then using Object.keys to search for it... I've offered an approach that does not change your json structure.

David Espino
  • 2,177
  • 14
  • 21
  • Updated my question. The main issue with the solution you gave is that all of this is happening on front end javascript. I did note nodejs but that is simply because I am building a nodejs application but this portion is all front end javascript. Will update and remove nodejs if you feel it is needed. – Zgbrell Dec 09 '16 at 00:36
0

Just use localstorage.getItem; it returns null if the key doesn't already exist.

Sean
  • 25
  • 9