Magento 2 – Knockout.js Minicart Implementation Guide

magento-2.1mini-cartxml

My current theme has a layout inside of the following:

Theme/default/Magento_Theme/layout/default.xml

Inside of this I have removed the header and rebuilt it like so:

 <referenceContainer name="header.container">
        <container name="header-wrapper" label="Page Header" as="header-wrapper" htmlTag="div" htmlClass="header main-header">
            <block class="Magento\Theme\Block\Html\Header\Logo" name="logo">
                <arguments>
                    <argument name="logo_img_width" xsi:type="number">289</argument>
                    <argument name="logo_img_height" xsi:type="number">64</argument>
                </arguments>
            </block>
            <block class="Magento\Checkout\Block\Cart\Sidebar" name="minicart" as="minicart" after="logo" template="cart/minicart.phtml">
                <arguments>
                    <argument name="jsLayout" xsi:type="array">
                        <item name="types" xsi:type="array"/>
                        <item name="components" xsi:type="array">
                            <item name="minicart_content" xsi:type="array">
                                <item name="component" xsi:type="string">Magento_Checkout/js/view/minicart</item>
                                <item name="config" xsi:type="array">
                                    <item name="template" xsi:type="string">Magento_Checkout/minicart/content</item>
                                </item>
                                <item name="children" xsi:type="array">
                                    <item name="subtotal.container" xsi:type="array">
                                        <item name="component" xsi:type="string">uiComponent</item>
                                        <item name="config" xsi:type="array">
                                            <item name="displayArea" xsi:type="string">subtotalContainer</item>
                                        </item>
                                        <item name="children" xsi:type="array">
                                            <item name="subtotal" xsi:type="array">
                                                <item name="component" xsi:type="string">uiComponent</item>
                                                <item name="config" xsi:type="array">
                                                    <item name="template" xsi:type="string">Magento_Checkout/minicart/subtotal</item>
                                                </item>
                                            </item>
                                        </item>
                                    </item>
                                    <item name="extra_info" xsi:type="array">
                                        <item name="component" xsi:type="string">uiComponent</item>
                                        <item name="config" xsi:type="array">
                                            <item name="displayArea" xsi:type="string">extraInfo</item>
                                        </item>
                                    </item>
                                    <item name="promotion" xsi:type="array">
                                        <item name="component" xsi:type="string">uiComponent</item>
                                        <item name="config" xsi:type="array">
                                            <item name="displayArea" xsi:type="string">promotion</item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </argument>
                </arguments>
                <container name="minicart.addons" label="Mini-cart promotion block"/>
            </block>
            <block class="Magento\Framework\View\Element\Template" name="top.search" as="topSearch" template="Magento_Search::form.mini.phtml" />
        </container>
    </referenceContainer>

This rebuilds my header in the layout i want, however doing this results in the following error:

knockout.js:3012 Uncaught TypeError: Unable to process binding "if: function (){return getCartParam('summary_count') }"
Message: Unable to process binding "foreach: function (){return { data:getCartParam('items'),as:'item'} }"
Message: Unable to process binding "foreach: function (){return $parent.getRegion($parent.getItemRenderer(item.product_type)) }"
Message: Cannot read property 'configurable' of undefined
    at UiClass.getItemRenderer (minicart.js:127)
    at foreach (eval at createBindingsStringEvaluator (knockout.js:2624), <anonymous>:3:93)
    at knockout.js:3889
    at Object.init (knockout.js:5023)
    at init (knockout.js:3914)
    at knockout.js:2989
    at Object.ignore (knockout.js:1249)
    at knockout.js:2988
    at Object.arrayForEach (knockout.js:151)
    at applyBindingsToNodeInternal (knockout.js:2974)

Now i've tried the following:

1/ Replace the minicart.phtml file from theme (app\design\frontend\Theme_namespace\Theme_module\Magento_Ch‌​eckout\templates\car‌​t) with core template (vendor\magento\module-checkout\view\frontend\templates\cart‌​).

2/ Replace content.html file from your theme (app\design\frontend\Theme_namespace\Theme_module\Magento_Checkout\web\template\minicart\content.html) with core template (vendor\magento\module-checkout\view\frontend\web\template\minicart\content.html)

3/ Remove all pub/static/frontend , remove var folder. Run deploy static content again : php magento setup:static-content:deploy

from this post but this doesn't fix my problem. Im not 100% sure what is causing my issue, but i know it relates to the new mini-cart block i've added into the header, as removing this means I get no error.

If anyone has any info that'd be awesome.

Best Answer

Looks as though inside of your theme default.xml you are calling header.container again.

This will result in the error, you're trying to overwrite a reference block that already exsists - doubling up on the page the knockout that is being called, so what you actually need to do is the following:

add a new folder inside of your magento_theme called page_layout and copy the files from the core into there:

1column.xml

2columns-left.xml

Then you need to change the container for the header to be called something different, for example:

header.container.new

inside of your default.xml like so:

Then you need to add inside of your 1column change:

<container name="header.container" as="header_container" label="Page Header Container" htmlTag="header" htmlClass="page-header" before="main.content"/>

to

<container name="header.container.new" as="header_container_new" label="Page Header Container" htmlTag="header" htmlClass="page-header" before="page.top"/>

This will result in the error going and the header now working correctly.

Related Topic