Updating cart page with or without refresh after Queue is finished

Solved
Astronaut
1069 145 260

Hey everyone @Jason@Jasoliya  -- Any help would be appreciated . So I'm having a bit of an issue. I want to add free gifts after certain price breaks on the cart page, and also remove them if they aren't supposed to be there (for instance the gift at 100 dollars is in the cart, but the cart price is lower than 100 for some reason). I'm not having much trouble with this, but ideally I would like to update the cart without a refresh of the page. If I have to refresh the page, that's fine, but I would prefer not to. I am having trouble implementing this and having the page only refresh once. Maybe someone can tell me the best way to approach this. I'm just going to post a very simplified version of my code and only for adding the products:

 

    function freeGiftValidation(){

      let variant_array = [30107881668693,30107970142293]
      let cart = $.getJSON('/cart.js');
      Shopify.queue = [];
      cart.done(function(){
        cart = cart.responseJSON;
        let items = cart.items;

//to simplify things I am omitting my conditions and just using a forloop to push the items into the queue for (var i=0;i<variant_array.length;i++){ Shopify.queue.push({ variantId: variant_array[i] }) } if (Shopify.queue.length){ processQueue(); } function processQueue(){ if (Shopify.queue.length){ let request = Shopify.queue.shift(); Shopify.addItem(request.variantId, 1, processQueue); }else{ location.reload(); } } }) } freeGiftValidation();

This works, but will continuously reload the page, which I can see the reason. I have made other versions of basically the same code and have gotten them working. I'm trying to future proof this so that if we need to add more free gifts in the future that it will be as simple as adding them to the end of the array. Can someone enlighten me on a better approach for this? Thank you for your time.

If you'd like to make any edits to your store, please send me a personal message and we can discuss what you'd like to accomplish :D
0 Likes
Explorer
51 6 21

So I have done something similar to what you are looking for except in reverse. I am trying to remove multiple items when a certain item is removed, since we don't want them purchasing those items unless they purchase a specific item with it. Here is a link to the example product: https://ctoms.ca/products/red-kit-special-operations-capable-soc-kit this is a bundle/kit so it will add a bunch of things to your cart. The important thing is that if you remove the last trace system dual pattern rope from your cart it will also remove both the quickie descender and quickie ascender. You can test this out in either the mini cart on the cart page. On the cart page you will notice it only refreshes once, you could make it not refresh by writing some JavaScript/Jquery to remove or add products when they click the buttons. Here is the code I use to get that affect:

 

CartPageRemove.prototype.deleteMultiple = function(ids,idNum){
	if(idNum < ids.length - 1){
	  //console.log("test",ids,ids[idNum],idNum);
		$.ajax({
		    method: 'POST',
		    url: '/cart/change.js',
		    dataType: 'json',
		    data: {
		      quantity: 0,
		      id: ids[idNum]
		    }
	  	}).then(function(newCart) {
	    	this.deleteMultiple(ids,idNum + 1);
        }.bind(this)).catch(function(err){
          console.log(err)
        });
	}
	else{
		$.ajax({
		    method: 'POST',
		    url: '/cart/change.js',
		    dataType: 'json',
		    data: {
		      quantity: 0,
		      id: ids[idNum]
		    }
	  	}).then(function(newCart) {
	  		window.location.replace("/cart");
	  });
	}	
};

It is basically just calling itself until it reaches the end of a array of IDs I pass it. Each time the function is called it makes a post request to the cart API which just sets the value to 0. Once it reaches the end it causes a reload. You could probably use this exact function just change the quantity from 0 to whatever value you want. This is basically the same function use to add products to the cart as well. Let me know if you have any questions!

1 Like

Success.

Astronaut
1069 145 260

Dang, pushed off the first page already. Thank you @michaelPeterson  for your time and your code.  I understand your code but I don't exactly know how to tailor it to my approach. I kind of have tunnel vision right now, but it ended up paying off. So I erased all of my code and just started from scratch going step by step, what do I need. I think I was sending conflicting messages to my code because I was trying to use the same queue for both adding and removing the products. Also I had a bit of a logic error when I was pushing my elements into my removing array. I was making the mistake that my gifts would always be in the same order(which they are now, but that's still not how I identify them). So it was removing things I didnt want it to remove, in which case it was changing the order when my code would check the conditions again and re add them. If anyone else is looking to do something similar, this is how I achieved mine. Little hairy in some places, but it works :) 

    function freeGiftValidation(){
      Shopify.queue=[]
      let cart = jQuery.getJSON('/cart.js');
      cart.done(function(){
        cart = cart.responseJSON;
        let items = cart.items;
        let total_price = cart.total_price;
        let free_gift_array = [30107881668693, 30107970142293, 30258839748693]
        let conditions = [3000, 10000, 15000];
        let removeQueue = [];
        let item_ids = items.map(x => x.variant_id)
        let valid_conditions = conditions.filter(x => total_price >= x);
        let invalid_conditions = conditions.filter(x => total_price < x);
        // if conditions are valid push the free gift into the array
        for(var i=0;i<valid_conditions.length;i++){
          if (item_ids.indexOf(free_gift_array[i]) == -1){
            Shopify.queue.push(free_gift_array[i]);
          }
        }

        // if there are invalid conditions, find the index of the condition, and use it to access the free gift array to get the correct item
        for(var i=0;i<invalid_conditions.length;i++){
          if (item_ids.indexOf(free_gift_array[conditions.indexOf(invalid_conditions[i])]) != -1){
            removeQueue.push(free_gift_array[conditions.indexOf(invalid_conditions[i])]);
          }
        }
        console.log(free_gift_array, removeQueue);

        function applyGifts(){
          if (Shopify.queue.length){
            let request = Shopify.queue.shift();
            Shopify.addItem(request, 1, {}, applyGifts);
          }else{
            location.reload();
          }
        }
        function removeGifts(){
          if (removeQueue.length){
            let request = removeQueue.shift();
            Shopify.removeItem(request, removeGifts);
          }else{
            location.reload();
          }
        }

        // if the add queue has anything in it, run the function
        if (Shopify.queue.length){
          applyGifts();
        }
        // if the remove queue has anything in it, run this function
        if(removeQueue.length){
          removeGifts();
        }

      });
    }
    freeGiftValidation();

I run this in cart.liquid. free_gift_array are the variant ids for my free gifts in order, and conditions is an array of their prices they have to hit (30.00, 100.00, 150.00). Should be able to copy and paste to your store and just change those arrays. Will update if I see any issues, but it seems to be working quite well.

If you'd like to make any edits to your store, please send me a personal message and we can discuss what you'd like to accomplish :D
1 Like
Explorer
51 6 21

No problem and thanks for sharing your code! It is always interesting seeing other peoples approach to problems. I am guessing the Shopify object you use is doing something similar to what my code does. I also have never seen that Shopify object before is it a third party library? It looks like it could be super useful.

0 Likes
Astronaut
1069 145 260

If you're talking about the queue, it's not something that Shopify has by default. I made it at the top of the function because I was initially going off of this little bit on the shopify ajax api:

 

https://help.shopify.com/en/themes/development/getting-started/using-ajax-api#youre-building-a-quick...

 

I also thought it was like a global variable that Shopify has for this kind of thing, but apparently you can just define variables off of the Shopify object. Im pretty sure it can be any array, but I don't really feel like touching it now that I've got it working so I'm just going to leave it as Shopify.queue, even though it would probably make more sense to call it "addQueue" or something. 

If you'd like to make any edits to your store, please send me a personal message and we can discuss what you'd like to accomplish :D
1 Like
Explorer
51 6 21

Oh interesting I thought Shopify had some global object that had some built in methods. That would be great if they ever did add something like that, since adding/removing multiple things from the cart seems to be a common issue. It would also make modifications and building themes a lot easier since there would be a standard way of doing some things. Anyways glad you got it working and I like the one line array filter. I wasn't even aware of that method, I usually loop through the array and then apply the condition but that little method will save me a lot of for loops lol.

1 Like
Astronaut
1069 145 260

Yeah .map() and .filter() are extremely useful for looping through arrays. I usually loop through them too, but since I erased my code and started over from scratch anyway I figured I'd try to make them look neater. I really like this little website: Edabit

 

It has a lot of fun little challenges for various coding languages. One of my biggest things when I started doing javascript was like "...well what the hell do I want to do" --  Each challenge has a nice little resources tab that people who have already done the challenge link to that will help you complete the challenge. After you solve it, you also get access to all the other answers that people have submitted so you can see who did things more efficiently and whatnot. That's where I learn a lot of new methods.

If you'd like to make any edits to your store, please send me a personal message and we can discuss what you'd like to accomplish :D
0 Likes