0

How can we display the shipping cost in the mini cart subtotal?

At the moment we only have the subtotal in the mini cart.

We tried a lot in the mini cart tax template;

/Magento_Tax/web/template/checkout/minicart/subtotal/totals.html

data-bind="html: cart().shippingAmount"
data-bind="html: cart()['shipping_amount']"

But we can not get the value, what are we missing here?

1 Answer 1

1

Looking at a 2.4.2 site, the shipping amount isn't stored with the cart data used by that template.

(Also, I don't think shipping cost is calculated until the customer visits the cart page, even if it is flat rate. But that is a separate issue.)

The template's cart data is set in:

vendor/magento/module-tax/view/frontend/web/js/view/checkout/minicart/subtotal/totals.js

initialize: function () {
    this._super();
    this.cart = customerData.get('cart');
}

You would have to make cart-data available to the template and get the shipping amount from its totals.

The data included in each can be seen by running the following in the browser console:

require([
    'Magento_Customer/js/customer-data'
], function(
    customerData
) {
    console.log(customerData.get('cart')());
    console.log(customerData.get('cart-data')());
});

To make cart-data available to the template, you would need to override totals.js with a modified copy in your design files, i.e.:

app/design/frontend/[your theme]/luma/Magento_Tax/web/js/view/checkout/minicart/subtotal/totals.js

In the following example, cart-data is made available.

Since cart-data may be empty, a wrapper is also added to return the shipping amount only when available (Note the comma added between initialize and getShippingAmount):

initialize: function () {
    this._super();
    this.cart = customerData.get('cart');
    this.cartData = customerData.get('cart-data');
},

getShippingAmount: function() {
    if (this.cartData() && this.cartData().totals) {
        return this.cartData().totals.shipping_amount;
    }
}

With these changes in place, the template supports, e.g.:

data-bind="html: getShippingAmount()

You could also create a mixin or override in a custom extension.

E.g.

app/code/Your/Extension/view/frontend/requirejs-config.js:

var config = {
    'config': {
        'mixins': {
            'Magento_Tax/js/view/checkout/minicart/subtotal/totals': {
                'Your_Extension/js/view/checkout/minicart/subtotal/totals-mixin': true
            },
        }
    }
};

app/code/Your/Extension/view/frontend/web/js/view/checkout/minicart/subtotal/totals-mixin.js:

define([
    'Magento_Customer/js/customer-data'
], function (customerData) {
    'use strict';

    return function (Component) {
        return Component.extend({
            initialize: function () {
                this._super();
                this.cartData = customerData.get('cart-data');
            },

            getShippingAmount: function() {
                if (this.cartData() && this.cartData().totals) {
                    return this.cartData().totals.shipping_amount;
                }
            }
        });
    }
});
4
  • Thanks! Is it also now possible to check if the customer is loggedin? isLoggedIn seems not working.
    – JGeer
    May 21, 2021 at 9:01
  • Sadly it does not work well with logged out customers, then we face the JS error: Message: undefined is not an object (evaluating 'cartData().totals.shipping_amount')
    – JGeer
    May 21, 2021 at 10:42
  • 1
    I updated the answer to account for situations where cartData().totals.shipping_amount would cause an error because the information is unavailable. As far as I can tell, this is true for not-logged-in customers until they visit the cart page.
    – jiheison
    May 21, 2021 at 16:20
  • Thanks a lot, works perfect now!
    – JGeer
    May 21, 2021 at 19:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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