Adding Multiple Products to Cart on One Click

rumleydev
Tourist
12 1 0

I am attempting to post 2 items to a shopping cart, in one click. I've built a form with hidden checkboxes that carry the relevant product attributes I need to do that. I have a loop going over the form's child checkboxes to pull that info and invoke the function for the post request.

The problem is that sometimes it does add both items (yay!) but sometimes it'll load only the first item and sometimes only the second item. There's no error code in the console for me to go off of so I'm wondering what I'm missing.

I think it has something to do with asynchronous requests being made. I can see both requests firing off in the network tab of my Chrome Dev Tools. But I'm not sure how to implement that here.

The HTML:

<div id="form-wrapper">
    <form id='free-addon-form'>
        <input 
           type="checkbox" 
           name="paid-plan" 
           id="paid-plan-option-annual"
           data-variant-id="{{ p_annual.selected_or_first_available_variant.metafields.subscriptions.discount_variant_id }}" 
           data-variant-interval-value="{{ p_annual.metafields.subscriptions.shipping_interval_frequency }}" 
           data-variant-interval-unit="{{ p_annual.metafields.subscriptions.shipping_interval_unit_type }}"
           data-quickadd-id="{{ p_annual.selected_or_first_available_variant.id }}"
           data-quickadd-properties
           checked    
       >
       <input 
           type="checkbox" 
           name="free-addon" 
           id="paid-plan-option-freebie"
           data-variant-id="{{ p_free.selected_or_first_available_variant.metafields.subscriptions.discount_variant_id }}"
           data-quickadd-id="{{ p_free.selected_or_first_available_variant.id }}"
           data-quickadd-properties
           checked    
       >
       <button class="btn"
               type="submit" 
               name="free-addon-submit" 
               id="" 
       >
       {{ p_annual.selected_or_first_available_variant.price | money_without_trailing_zeros }}{{ section.settings.productlink1label }}
       </button>
    </form>
</div>

 
My JS

const freeAddOnForm = document.getElementById('free-addon-form'),
      freeAddOnButton = freeAddOnForm[2];

function getDataForm(e) {
    e.preventDefault();

    loadingBarTrigger('start');

    for(let i = 0; i < 2; i++) {
        itemAdd(
            freeAddOnForm[i].getAttribute('data-quickadd-id'), 
            freeAddOnForm[i].getAttribute('data-quickadd-properties'), 
            (freeAddOnForm[i].getAttribute('data-quickadd-quantity'))
                ? freeAddOnForm[i].getAttribute('data-quickadd-quantity')
                : 1, 
            (!html.is('#cart')) ? true : false,
            (html.is('#cart')) ? true : false
        )
    }   
}

document.addEventListener('DOMContentLoaded', function (){
    freeAddOnButton.addEventListener('click', getDataForm, false);
})

 

The theme's code for adding a single item that I was trying to replicate:

_document.on('click', '[data-quickadd-id]', function() {
    let _this = $(this);

    loadingBarTrigger('start');

    itemAdd(
        _this.attr('data-quickadd-id'), 
        _this.attr('data-quickadd-properties'), 
        (_this.attr('data-quickadd-quantity'))
            ? _this.attr('data-quickadd-quantity')
            : 1, 
        (!html.is('#cart')) ? true : false,
        (html.is('#cart')) ? true : false
    );
});

 

The itemAdd function that makes the post request to the cart:

const itemAdd = (variantId, properties, qty, openCart, reloadPage) => {
    $.ajax({
        type: 'POST',
        dataType: 'html',
        url: `/cart/add.js`,
        data: 
            {
                id: variantId,
                quantity: qty,
                properties: (properties) 
                    ? JSON.parse(properties) : null
            },
        error: function(data) {
            console.error(data);

            loadingBarTrigger('done');
        },
        success: function() {
            loadingBarTrigger('move');

            $.ajax({
                url: '/cart',
                dataType: 'html',
                error: function(data) {
                console.error(data);

                loadingBarTrigger('done');
            },
                success: function(data) {
                    let minicartContent = $('#minicart-content');
                    let cartItemsHtml = $(data).find('#cart-content #cart-items').html();

                    // insert or prepend cart HTML
                    (minicartContent.find('#cart-items').length)
                        ? minicartContent.find('#cart-items').html(cartItemsHtml)
                        : minicartContent.prepend(cartItemsHtml);

                    // remove giftbox content if exists
                    (minicartContent.find('#cart-giftbox .item-info').length)
                        ? minicartContent.find('#cart-giftbox .item-info').remove()
                        : '';

                    loadingBarTrigger('done');
                    cartTotalUpdate();

                    // open cart
                    (openCart && !html.is('#cart'))
                        ? minicartTrigger.trigger('click') : '';

                    (reloadPage)
                        ? location.reload() : '';
                }
            });
        }
    });
}

 

Thoughts?

0 Likes
rumleydev
Tourist
12 1 0

bump

0 Likes
rumleydev
Tourist
12 1 0

Thinking that it's the open cart function at the end of itemAdd that is causing the problem. Both request are being made and returned. Unsure where to put that logic though.

0 Likes
rumleydev
Tourist
12 1 0

Here's a blog post that describes my issue. I'm going to have to build an array of objects to push to the itemAdd function.

http://www.codeshopify.com/blog_posts/how-to-add-multiple-products-with-an-ajax-cart

0 Likes