4
votes

I am trying to figure out how to adjust multiple cart items.

Essentially, we have a custom order page which adds multiple products to the cart. All of the products added have the same unique property.

For example, these two products are added to the cart:

Product 1
ID: 1000
Property: CustomProduct2

Product2 
ID: 1001
Property: CustomProduct2

The end-user just sees this as one product so I would like a way to remove or adjust the quantities for all products with matching properties with one button.

I know the below wont work but presume if possible, it would be something along the lines of:

$(document).on('click','.remove',function(e){
  var property = $(this).attr('data-property');
       $.ajax({
         type: 'POST',
         url: '/cart/add.js',
         data: {
           quantity: 0,
           id: *,
           properties: {
             'Property': data-property
           }
         },
         dataType: 'json',
         async:false,

       });
     });
2

2 Answers

5
votes

This can be achieved by using the /cart/update.js endpoint. (See Shopify's official documentation

One point that the documentation omits is that you can use either the variant ID or the line-item's 'key' value as the key for the payload. This is important when using line-item properties, as the same variant ID may exist on multiple lines if it has been added multiple times with different line-properties each time. The key, however, is guaranteed to be unique for every line in the cart.

An example request would therefore be:

$.ajax({
     type: 'POST',
     url: '/cart/update.js',
     data: {
       updates:{
          "100000:abcdef":0, // Use the line-item key inside the quotes 
          "100001:xyzwnm":0
       }
     },
     dataType: 'json',
     async:false,  // Be warned, async:false has been deprecated in jQuery for a long time and is not recommended for use. It's generally recommended to use callbacks or promises instead

   });

One way you might create your updates data could be through a simple for loop. Assuming you have the current contents of the cart saved to a variable named cart, that might look like:

var updateData = {}
for(var i=0; i < cart.items.length; i++){
  var item = cart.items[i];
  if( /* Check for item that needs to be removed */){
    updateData[item.key] = 0;
  }
}
// Now you can make your AJAX call using this updateData object

You could also do this using array.reduce if you wanted to be fancy:

var updateData = cart.items.reduce(function(acc, item){
  if( /* Check for item that we want to remove */){
    acc[item.key] = 0
  }
  return acc;
}, {})
// Now make your AJAX call using the updateData that we created

Either way, our final AJAX call will now look something like this:

$.ajax({
 type: 'POST',
 url: '/cart/update.js',
 data: {
   updates: updateData
 },
 dataType: 'json',
 success: function(cart){ console.log('Hooray!', cart) },
 error: function(err){ console.error('Booo!', err) }

});

Hope this helps!

0
votes

Remove with fetch

Removing a single item from the cart.

function removeItemFromCart (item) {
  fetch('/cart/update.js', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      updates: {
        [item.key]: 0
      }
    })
  }).then(response => response.json())
    .then((newCart) => {
      console.log('Updated cart:', newCart)
    })
    .catch(console.error)
}