Magento2 Minicart – Update Minicart After Adding Products Programmatically

magento2

I'm adding products programmaticaly in my module. I've created etc/frontend/sections.xml file with following content:

<?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="modextend/cart/addProducts">
        <section name="cart"/>
    </action>
</config>

And it's routes.xml content:

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="standard">
        <route id="modextend" frontName="modextend">
            <module name="Vendor_ModulesExtend" />
        </route>
    </router>
</config>

And for some reason minicart isn't updating itself after using my controller. Products are added successfully because I can see them in checkout and cart.

Do you know why isn't it working?

Edit:
I've tried it also by AJAX request:

var url = '/modextend/cart/addProducts/products_ids/';
//selectedAccessories is array of products id's
url += selectedAccessories.join(',');

$.ajax(
    url,
    {method: 'post'}
).done(function(res)
{
    console.log(res);
});

And its my controller action:

$products = $this->getRequest()->getParam('products_ids');
$result = [];

if($products)
{
    $products = explode(',', $products);

    try {
        $this->cart->addProductsByIds($products);
        $this->cart->save();

        $result['success'] = true;
        $this->messageManager->addSuccess(__('Selected accessories has been added to your cart.'));
    } catch (LocalizedException $e) {
        $result['error'] = true;
        $this->messageManager->addException(
            $e,
            __('%1', $e->getMessage())
        );
    } catch (\Exception $e) {
        $result['error'] = true;
        $this->messageManager->addException($e, __('There was an error while adding accessories to your cart.'));
    }
}

$this->getResponse()->representJson(
    $this->_objectManager->get('Magento\Framework\Json\Helper\Data')->jsonEncode($result)
);

Best Answer

I finally got it working.

The problem was, that form I was creating in js wasn't appended to body.

Here you have request sended via js:

var url = '/modextend/cart/addProducts/';

if(selectedAccessories.length === 0)
{
    return false;
}

var form = $('<form>').attr('action', url).attr('method', 'post');
var input = $('<input type="hidden" name="products_ids" />').val(selectedAccessories.join(','));
input.appendTo(form);

form.appendTo('body').hide().submit();

appendTo('body') is here critical part.

And in controller standard redirect to cart:

$products = $this->getRequest()->getParam('products_ids');
$resultRedirect = $this->resultRedirectFactory->create();

if($products)
{
    $products = explode(',', $products);

    try {
        $this->cart->addProductsByIds($products);
        $this->cart->save();

        $this->messageManager->addSuccess(__('Selected accessories has been added to your cart.'));
    } catch (LocalizedException $e) {
        $this->messageManager->addException(
            $e,
            __('%1', $e->getMessage())
        );
    } catch (\Exception $e) {
        $this->messageManager->addException($e, __('There was an error while adding accessories to your cart.'));
    }
}

$resultRedirect->setPath('checkout/cart/index');

return $resultRedirect;