10

I have the following class i am using to test adding to cart in a custom way;

use Magento\Framework\App\Action;
use Magento\Checkout\Model\Cart;

class Add extends Action\Action
{
    protected $cart;

    public function __construct(
        Action\Context $context,
        Cart $cart
    ){
        $this->cart = $cart;
        parent::__construct($context);
    }

    public function execute()
    {
        $this->cart->addProductsByIds([1])
            ->save();
    }
}

This works great. When you view the cart it shows my item, all looks cool in the database etc. However, the minicart still shows as if there are no items in the basket.

If i then add another product to the cart using the "add to cart" button on the product or listing pages it adds to the cart and updates the minicart to show both items.

Where does it trigger the minicart to update itself or how does the minicart know it needs to refresh?

3 Answers 3

38

Thanks for your help :)

I have found how to trigger it, you need to set up a sections.xml inside etc/frontend of your module that tells Magento which sections to update for a given Ajax call. Here is an example;

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Customer:etc/sections.xsd">
    <action name="[frontName]/[ActionPath]/[ActionName]">
        <section name="cart"/>
    </action>
</config>

After my Ajax call has finished to [frontName]/[ActionPath]/[ActionName] Magento makes another call to /customer/section/load passing the sections to load.

By default it requests any messages but if you have set up your sections.xml correctly you will also see the section names you have defined in there as well.

7
  • @smartic,Good information i got clew from here
    – Amit Bera
    Mar 26, 2016 at 10:30
  • Please help with magento.stackexchange.com/questions/166641/…
    – Jackson
    Mar 29, 2017 at 3:42
  • Awesome, I was working on updating other blocks via ajax and this got me there. Thanks for posting your solution.
    – Eirik
    Apr 10, 2017 at 21:21
  • @Smartie is there any way to update cart section after some magento api call?
    – ND17
    May 12, 2017 at 5:56
  • 1
    @Smartie For multiple adding products, it is only updating quantity of first product and rest product count is not shown in mini cart. Do we nee d to add anything more here?
    – DEEP JOSHI
    Nov 24, 2017 at 14:00
8

This isn't directly related to the question, but if you are updating the cart via AJAX calls in normal Magento require.js files, you can require the Magento_Customer/js/customer-data object and ask the minicart to refresh this way, as well:

<script>
    require([
        'Magento_Customer/js/customer-data'
    ], function (customerData) {
        var sections = ['cart'];
        customerData.invalidate(sections);
        customerData.reload(sections, true);
    });
</script>

Source: https://github.com/magento/magento2/issues/5621

1
  • So i made it here looking for a solution for my custom page_layout. My mini cart count was always 0 whenever i went to any of my custom pages. I ended up having to run customerData.invalidate(sections); and then Magento was able to do the rest. Mar 19, 2018 at 16:22
2

In storefront if you dive in source in minicart area

<div data-block="minicart" class="minicart-wrapper">
  <a class="action showcart" 
   data-bind="scope: 'minicart_content'">
     ... 
  </a>

   <script type="text/x-magento-init">
   {
    "[data-block='minicart']": {
        "Magento_Ui/js/core/app": {"components":{....}
     }
   }
</script>
</div>

As you can see here magento2 execute components inside script tag and dynamic bind data to block minicart use knockoutJs

Somethings interesting i discover

\vendor\magento\module-checkout\view\frontend\layout\default.xml

From Checkout layout. It define a component for minicart-content to getdata Continue see Magento_Checkout/js/view/minicart you will see

.....
$('[data-block="minicart"]').on('contentLoading', function(event) {
      addToCartCalls++;
      self.isLoading(true);
});
.....

Your Answer

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

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