4

I want to get Cart items collection on product page.

customer-data.js

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

    return Component.extend({
        /** @inheritdoc */
        initialize: function () {
            this._super();
            this.items = customerData.get('cart')().items //get cart items
            console.log(this.items);
        }
    });
});

product.phtml

<div class="col-md-12" data-bind="scope: 'section'" style="padding: 0;">
    <!-- ko template: getTemplate() --> 
        <!-- ko if: items() -->
            <a class="action primary checkout" style="text-align: center;margin-top: 5px;" href="#"> Product ID</a>
        <!-- /ko -->
    <!-- /ko -->
</div>

<script type="text/x-magento-init">
    {
        "*": {
            "Magento_Ui/js/core/app": {
                "components": {
                    "section": {
                        "component": "Codism_Customblock/js/customer-data"
                    }
                }
            }
        }
    }
</script>

Help me.

Masud Shaikh
  • 1,189
  • 20
  • 50

1 Answers1

8

On the product page you can use a customer data in js:

require('Magento_Customer/js/customer-data').get('cart')().items

This is a preferred way because if you load that items on the backend (php) it will not work with a full page cache.

list of items on the product view page


Update with example code:

Note: full code available in example module on GitHub

Here is my example based on your code:

Adding block to the product page (for test purposes it will be place just right in the content area)

app/code/MageWorx/CustomProductPage/view/frontend/layout/catalog_product_view.xml

<?xml version="1.0"?>

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceContainer name="content">
            <block class="Magento\Framework\View\Element\Template"
                   name="custom.product.info.cart.items"
                   template="MageWorx_CustomProductPage::cart_items.phtml"/>
        </referenceContainer>
    </body>
</page>

Creating template with our component and configuration:

app/code/MageWorx/CustomProductPage/view/frontend/templates/cart_items.phtml

<div class="col-md-12" data-bind="scope: 'cart-items-section'" style="padding: 0;" id="cart-items-section">
    <!-- ko template: getTemplate() --><!-- /ko -->
</div>

<script type="text/x-magento-init">
    {
        "*": {
            "Magento_Ui/js/core/app": {
                "components": {
                    "cart-items-section": {
                        "component": "MageWorx_CustomProductPage/js/cart-items"
                    }
                }
            }
        }
    }
</script>

Creating a component itself (.js part, e.g. MageWorx_CustomProductPage/js/cart-items):

app/code/MageWorx/CustomProductPage/view/frontend/web/js/cart-items.js

define([
    'jquery',
    'ko',
    'uiComponent',
    'Magento_Customer/js/customer-data',
    'uiRegistry'
], function ($, ko, Component, customerData, registry) {
    'use strict';

    return Component.extend({
        defaults: {
            template: 'MageWorx_CustomProductPage/product/cart-items'
        },

        observableProperties: [
            'items'
        ],

        /** @inheritdoc */
        initialize: function () {
            this._super();

            var self = this;

            customerData.get('cart').subscribe(
                function (cartData) {
                    console.log(cartData);
                    self.items(cartData.items);
                }
            );

            this.items(customerData.get('cart')().items); //get cart items
            console.log(this.items());
        },

        initObservable: function () {
            this._super();
            this.observe(this.observableProperties);

            return this;
        }
    });
});

Here is some clarifications:

  1. We use custom template named MageWorx_CustomProductPage/product/cart-items to render items.
  2. We use customer data as a source for items.
  3. Items property is observable part of our component (see observableProperties prop. and initObservable function), where all items from customer data will be stored.
  4. Each time when the customer data updated we synchronize our items property with the items in cart (see customerData.get('cart').subscribe part of init function body).

Adding main template:

app/code/MageWorx/CustomProductPage/view/frontend/web/template/product/cart-items.html

<div style="float: left" data-bind="visible: items().length">
    <h3 data-bind="i18n: 'Cart items template'"></h3>
    <ul>
    <!-- ko foreach: items -->
        <li>
            <!-- ko template: 'MageWorx_CustomProductPage/product/item' --><!-- /ko -->
        </li>
    <!-- /ko -->
    </ul>
</div>
<div style="float: left" data-bind="visible: !items().length">
    <!-- ko i18n: 'There no items in your cart' --><!-- /ko -->
</div>

Adding a sub-template responsible for render of an each item from a cart:

app/code/MageWorx/CustomProductPage/view/frontend/web/template/product/item.html

<h3><!-- ko i18n: 'Item id: ' --><!-- /ko --><!-- ko text: item_id --><!-- /ko --></h3>
<span data-bind="text: product_name"></span>
<img data-bind="attr: {src: product_image.src, alt: product_image.alt}"/>
<span data-bind="html: product_price"></span>

Result with 1 item:

result with 1 item in cart

Result when adding second item:

result with 2 items

Result when all items removed through mini-cart on same page:

result without items

PS: do not forget to remove the console.log() from code when all will be done.

Siarhey Uchukhlebau
  • 15,957
  • 11
  • 54
  • 83