Reputation: 37
I'm attempting to add 3 items to the cart in a loop. Firebug reports each individual ajax call to '/cart/add.js' is returning with a 200 OK, and the json object being returned shows the correct variant_id and quantity that was just added. However, the resulting contents of the cart is usually incorrect - often showing only 1 or 2, rather than the expected 3 items.
Here is my code.
$('form[name="one-step-checkout"]').submit(function(event) {
event.preventDefault();
Shopify.clear(function(cart) {
add_items(function() {
Shopify.getCart(function(cart) {
alert('items in cart : ' + cart.items.length)
})
});
});
});
add_items = function(callback) {
add_variant_array = [];
$('form[name="one-step-checkout"]').find('div.checkout-step-options input:radio').each(function() {
if($(this).is(':checked') && $(this).attr('name') == 'price') {
var choice = $(this).val();
$('input.variant-price.' + choice).each(function() {
var variant_id = this.id;
add_variant_array.push(Shopify.addItem(variant_id, 1));
});
}
});
if (typeof callback == "function") {
$.when.apply($, add_variant_array).done(function() {
alert('done adding to cart');
});
callback();
}
};
If I repeatedly submit the form, the number of items in the cart varies between 1 and 3. The only thing I can think of is that the cart is somehow being cleared in the middle of the operation. I thought the callback being passed to the Shopify.clear() function was't executed until after a success was received? no?
many thanks in advance for any pointers!
Upvotes: 1
Views: 4115
Reputation: 37
The Shopify ajax calls were being fired off as soon as I added them to the array. meeech pointed out, correctly, that the Shopfiy ajax api requires I wait for a successful return message between each ajax call. My code was essentially spraying out the requests all at once.
To fix this, I wrote a function that calls itself recursively to ensure each request isn't fired until the previous one returns. I then pass in an array of arguments and a corresponding array of functions to be executed in sequence. With each call to itself, it removes an argument and a function until there are none left.
$('form[name="one-step-checkout"]').submit(function(event) {
event.preventDefault();
Shopify.clear(function() {
var variants = get_variants();
var tasks = []
for (i = 0; i < variants.length; i++) {
tasks.push(Shopify.addItem);
}
// add the shopify items in order
sequencer(variants, tasks, function() {
goto_cart();
});
});
});
sequencer = function(args, tasks, callback) {
if (tasks.length < 1) {
callback();
} else {
task = tasks.shift();
arg = args.shift();
task(arg, 1, function() {
sequencer(args, tasks, callback); // keep passing the original callback forward
});
}
}
get_variants = function() {
var variants = [];
$('form[name="one-step-checkout"]').find('div.checkout-step-options input:radio').each(function() {
if($(this).is(':checked') && $(this).attr('name') == 'price') {
var choice = $(this).val();
$('input.variant-price.' + choice).each(function() {
variants.push(this.id);
});
}
});
return variants;
};
Upvotes: 1
Reputation: 1397
2 possibilities:
A) You mention you are using a loop. Are you waiting for the one request to finish before adding the new one? From the head of the api.jquery.js file.
"Ajax requests that update Shopify's cart must be queued and sent synchronously to the server. Meaning: you must wait for your 1st ajax callback to send your 2nd request, and then wait for its callback to send your 3rd request, etc."
B) When working on a client site, I had to change getCart so that it wouldn't cache the data. This was mainly a problem on IE, but that might be another source of your issue. So, getCart was changed to:
Shopify.getCart = function(callback) {
jQuery.ajax({
dataType: "json",
url: '/cart.js',
cache: false,
success: function (cart, textStatus) {
if ((typeof callback) === 'function') {
callback(cart);
}
else {
Shopify.onCartUpdate(cart);
}
}
});
};
HTH
Upvotes: 3