Search code examples
shopify

Shopify - remove/change quantity of multiple cart items


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,

       });
     });

Solution

  • 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!