skip to Main Content

I have the following function to check whether a product can be added to cart and do things after

// Add item to cart
function add_cart_item(variant_id, qty, callback) {
  $.post('/cart/add.js', {
    quantity: qty,
    id: variant_id
  }, null, "JSON")
  .done(function() {
    // Do stuff after product is added to cart
    // Update cart product count
    refresh_cart('add', variant_id);
    
    // Callback
    if (typeof callback === 'function') { 
      callback();
    }
  })
  .fail(function(jqXHR) {
    handle_xhr(jqXHR);
  });
}

Elsewhere I replace the "Buy now" button text with a preloader until the request is complete, then return the original text with the following code

add_cart_item(variant.id, $('.quantity', $parent).val(), function(){
  // Enable button
  $button.prop('disabled', false).html($button_html);
});

This works until the post method in add_cart_item function fails (usually with 422 response), in which the button portion is no longer executed and is stuck in preloader state.

How can I make the button part of the code run regardless of whether the function succeeds or not, but still wait for it to complete the request before executing?

2

Answers


  1. Chosen as BEST ANSWER

    Found my own silly mistake. Turns out .fail doesn't prevent function callback, what does prevent it however is not having the code to execute the callback in the .fail portion of my function. So this fixed the issue:

    function add_cart_item(variant_id, qty, callback) {
      $.post('/cart/add.js', {
        quantity: qty,
        id: variant_id
      }, null, "JSON")
      .done(function() {
        // Do stuff after product is added to cart
        // Update cart product count
        refresh_cart('add', variant_id);
        
        // Callback
        if (typeof callback === 'function') { 
          callback();
        }
      })
      .fail(function(jqXHR) {
        handle_xhr(jqXHR);
    
       // Callback
        if (typeof callback === 'function') { 
          callback();
        }
      });
    }
    

  2. Presumably this is jQuery.

    Use .always instead of .done.

    From https://api.jquery.com/jquery.post/

    The jqXHR.done() (for success), jqXHR.fail() (for error), and
    jqXHR.always() (for completion, whether success or error; added in
    jQuery 1.6) methods take a function argument that is called when the
    request terminates.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search