materangai
materangai

Reputation: 109

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,

       });
     });

Upvotes: 4

Views: 7748

Answers (3)

Diego Fortes
Diego Fortes

Reputation: 9800

I coded a function to remove an item from the cart based on its variant's ID without jQuery. I hope it helps.

  function removeFromCartByVariantID(variantID) {
      // Fetch the current cart data
      fetch('/cart.js')
          .then(response => response.json())
          .then(cartData => {

              const lineItem = cartData.items.find(item => item.variant_id === parseInt(variantID));

              if (lineItem) {
                  fetch('/cart/update.js', {
                          method: 'POST',
                          credentials: 'same-origin',
                          headers: {
                              'Content-Type': 'application/json'
                          },
                          body: JSON.stringify({
                              updates: {
                                  [lineItem.key]: 0
                              }
                          }),
                      })
                      .then(response => {

                          if (!response.ok) {
                              throw new Error('Request failed with status ' + response.status);
                          }
                          console.log('Successfully removed item from the cart');
                      })
                      .catch(error => {
                          console.error('Error occurred:', error);
                      });
              } else {
                  console.log(`Item with variant ID ${variantID} not found in the cart`);
              }
          })
          .catch(error => {
              console.error('Error fetching cart:', error);
          });
  }

Usage:

removeFromCartByVariantID(39351307173911)

Upvotes: 0

Chris Hayes
Chris Hayes

Reputation: 13771

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)
}

Upvotes: 0

Dave B
Dave B

Reputation: 3248

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!

Upvotes: 5

Related Questions