0

When I am clicking on Add To Cart button then product was added to my cart and mini-cart count also updated but loader on mini-cart showing always.

enter image description here

After refreshing my page mini-cart shows updated count.

enter image description here

What should I do to remove that loader after mini-cart count update?

Update: Below is response of add to cart ajax call:

enter image description here

| improve this question | | | | |
  • Do you have any errors in the console that is preventing the javascript from stopping the loader after it is started? – LM_Fielding Jun 29 '17 at 15:23
  • @LM_Fielding Thanks for your reply. No error in my browser's console tab. – Nitesh Jun 30 '17 at 5:57
  • Check by changing deploy mode to PRODUCTION and enable cache. – Jai Jun 30 '17 at 7:01
  • Check the network tab on developer tools, the XHR to find the request for adding a product to cart, it may not be completing (staying at pending due to lag?) – LM_Fielding Jun 30 '17 at 11:03
  • @LM_Fielding I have added response in my question(200 OK). – Nitesh Jun 30 '17 at 12:22
2

Add to cart Ajax call is given in below js file:

/vendor/magento/module-catalog/view/frontend/web/js/catalog-add-to-cart.js

So we need to override it in your theme like following:

/app/design/frontend/custom_package_name/custom_theme_name/Magento_Catalog/web/js/catalog-add-to-cart.js

Following is default ajax call where we need to add some code:

$.ajax({
            url: form.attr('action'),
            data: form.serialize(),
            type: 'post',
            dataType: 'json',
            beforeSend: function() {
                if (self.isLoaderEnabled()) {
                    $('body').trigger(self.options.processStart);
                }
            },
            success: function(res) {
                if (self.isLoaderEnabled()) {
                    $('body').trigger(self.options.processStop);
                }

                if (res.backUrl) {
                    window.location = res.backUrl;
                    return;
                }
                if (res.messages) {
                    $(self.options.messagesSelector).html(res.messages);
                }
                if (res.minicart) {
                    $(self.options.minicartSelector).replaceWith(res.minicart);
                    $(self.options.minicartSelector).trigger('contentUpdated');
                }
                if (res.product && res.product.statusText) {
                    $(self.options.productStatusSelector)
                        .removeClass('available')
                        .addClass('unavailable')
                        .find('span')
                        .html(res.product.statusText);
                }
                self.enableAddToCartButton(form);
            }
        });
    },

Add below code in beforeSend() function:

          /*To hide loader on mini-cart*/
            $(".loading-mask").show();
            /*****************************/

Add below code in success() function:

       /*To hide loader on mini-cart*/
             setTimeout(function() {
                $(".loading-mask").hide();
             }, 3000);
        /*******************************/

Like below:

beforeSend: function() {
                if (self.isLoaderEnabled()) {
                    $('body').trigger(self.options.processStart);
                }
                /*To hide loader on mini-cart*/
                $(".loading-mask").show();
                /*****************************/

            },
success: function(res) {
                if (self.isLoaderEnabled()) {
                    $('body').trigger(self.options.processStop);
                }

                if (res.backUrl) {
                    window.location = res.backUrl;
                    return;
                }
                if (res.messages) {
                    $(self.options.messagesSelector).html(res.messages);
                }
                if (res.minicart) {
                    $(self.options.minicartSelector).replaceWith(res.minicart);
                    $(self.options.minicartSelector).trigger('contentUpdated');
                }
                if (res.product && res.product.statusText) {
                    $(self.options.productStatusSelector)
                        .removeClass('available')
                        .addClass('unavailable')
                        .find('span')
                        .html(res.product.statusText);
                }
                /*To hide loader on mini-cart*/
                setTimeout(function() {
                    $(".loading-mask").hide();
                }, 3000);
                /*******************************/
                self.enableAddToCartButton(form);
            }

I have used setTimeout() function to stop loader after mini-cart count increament.

| improve this answer | | | | |
0

To hide loader count at minicart.

Copy file from

vendor/magento/module-checkout/view/frontend/js/view/minicart.js

to your theme

app/design/frontend/{{VENDOR}}/{{THEME}}/Magento_Checkout/js/view/minicart.js

/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

define([
    'uiComponent',
    'Magento_Customer/js/customer-data',
    'jquery',
    'ko',
    'underscore',
    'sidebar',
    'mage/translate',
    'mage/dropdown'
], function (Component, customerData, $, ko, _) {
    'use strict';

    var sidebarInitialized = false,
        addToCartCalls = 0,
        miniCart;

    miniCart = $('[data-block=\'minicart\']');

    /**
     * @return {Boolean}
     */
    function initSidebar() {
        if (miniCart.data('mageSidebar')) {
            miniCart.sidebar('update');
        }

        if (!$('[data-role=product-item]').length) {
            return false;
        }
        miniCart.trigger('contentUpdated');

        if (sidebarInitialized) {
            return false;
        }
        sidebarInitialized = true;
        miniCart.sidebar({
            'targetElement': 'div.block.block-minicart',
            'url': {
                'checkout': window.checkout.checkoutUrl,
                'update': window.checkout.updateItemQtyUrl,
                'remove': window.checkout.removeItemUrl,
                'loginUrl': window.checkout.customerLoginUrl,
                'isRedirectRequired': window.checkout.isRedirectRequired
            },
            'button': {
                'checkout': '#top-cart-btn-checkout',
                'remove': '#mini-cart a.action.delete',
                'close': '#btn-minicart-close'
            },
            'showcart': {
                'parent': 'span.counter',
                'qty': 'span.counter-number',
                'label': 'span.counter-label'
            },
            'minicart': {
                'list': '#mini-cart',
                'content': '#minicart-content-wrapper',
                'qty': 'div.items-total',
                'subtotal': 'div.subtotal span.price',
                'maxItemsVisible': window.checkout.minicartMaxItemsVisible
            },
            'item': {
                'qty': ':input.cart-item-qty',
                'button': ':button.update-cart-item'
            },
            'confirmMessage': $.mage.__('Are you sure you would like to remove this item from the shopping cart?')
        });
    }

    miniCart.on('dropdowndialogopen', function () {
        initSidebar();
    });

    return Component.extend({
        shoppingCartUrl: window.checkout.shoppingCartUrl,
        maxItemsToDisplay: window.checkout.maxItemsToDisplay,
        cart: {},

        // jscs:disable requireCamelCaseOrUpperCaseIdentifiers
        /**
         * @override
         */
        initialize: function () {
            var self = this,
                cartData = customerData.get('cart');

            this.update(cartData());
            cartData.subscribe(function (updatedCart) {
                addToCartCalls--;
                // this.isLoading(addToCartCalls > 0);
                sidebarInitialized = false;
                this.update(updatedCart);
                initSidebar();
            }, this);
            $('[data-block="minicart"]').on('contentLoading', function () {
                addToCartCalls++;
                // self.isLoading(true);
            });

            if (
                cartData().website_id !== window.checkout.websiteId && cartData().website_id !== undefined ||
                cartData().storeId !== window.checkout.storeId && cartData().storeId !== undefined
            ) {
                customerData.reload(['cart'], false);
            }

            return this._super();
        },
        //jscs:enable requireCamelCaseOrUpperCaseIdentifiers

        isLoading: ko.observable(false),
        initSidebar: initSidebar,

        /**
         * Close mini shopping cart.
         */
        closeMinicart: function () {
            $('[data-block="minicart"]').find('[data-role="dropdownDialog"]').dropdownDialog('close');
        },

        /**
         * @return {Boolean}
         */
        closeSidebar: function () {
            var minicart = $('[data-block="minicart"]');

            minicart.on('click', '[data-action="close"]', function (event) {
                event.stopPropagation();
                minicart.find('[data-role="dropdownDialog"]').dropdownDialog('close');
            });

            return true;
        },

        /**
         * @param {String} productType
         * @return {*|String}
         */
        getItemRenderer: function (productType) {
            return this.itemRenderer[productType] || 'defaultRenderer';
        },

        /**
         * Update mini shopping cart content.
         *
         * @param {Object} updatedCart
         * @returns void
         */
        update: function (updatedCart) {
            _.each(updatedCart, function (value, key) {
                if (!this.cart.hasOwnProperty(key)) {
                    this.cart[key] = ko.observable();
                }
                this.cart[key](value);
            }, this);
        },

        /**
         * Get cart param by name.
         * @param {String} name
         * @returns {*}
         */
        getCartParam: function (name) {
            if (!_.isUndefined(name)) {
                if (!this.cart.hasOwnProperty(name)) {
                    this.cart[name] = ko.observable();
                }
            }

            return this.cart[name]();
        },

        /**
         * Returns array of cart items, limited by 'maxItemsToDisplay' setting
         * @returns []
         */
        getCartItems: function () {
            var items = this.getCartParam('items') || [];

            items = items.slice(parseInt(-this.maxItemsToDisplay, 10));

            return items;
        },

        /**
         * Returns count of cart line items
         * @returns {Number}
         */
        getCartLineItemsCount: function () {
            var items = this.getCartParam('items') || [];

            return parseInt(items.length, 10);
        }
    });
});

What we had done is commented the line

this.isLoading(addToCartCalls > 0);

and

self.isLoading(true);

If it helps please upvote. Thanks for your time to read the answer.

| improve this answer | | | | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.