Question

I have a simple uiCOmponent that I added to the checkout Layout to display in the jsLayout. The code looks like this.

component.html

<div class="delivery-estimation" data-bind="text: estimation"></div>

component.js

define([
    'uiElement'
], function(Component) {
    'use strict';
    return Component.extend({
        initialize: function () {
            this._super();
            // component initialization logic
            this.cart = [
                {'sku': '123456', 'delivery_status': 'available'},
                {'sku': '223456', 'delivery_status': 'available'},
                {'sku': '323456', 'delivery_status': 'unavailable'}
            ];
            //Testcode
            this.estimate(this.cart);
            this.estimation = `Test: ${this.cart[0].sku}`;
            return this;
        },

        estimate: function (cartData) {
            console.log(cartData);
        }
    });
});

checkout_index_index

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="checkout.root">
            <arguments>
                <argument name="jsLayout" xsi:type="array">
                    <item name="components" xsi:type="array">
                        <item name="checkout" xsi:type="array">
                            <item name="children" xsi:type="array">
                                <item name="component" xsi:type="array">
                                     <item name="sortOrder" xsi:type="string">0</item>
                                     <item name="component" xsi:type="string">Vendor_Module/js/view/component</item>
                                     <item name="template" xsi:type="string">Vendor_Module/component</item>
                                     <item name="displayArea" xsi:type="string">componentDisplayArea</item>
                                </item>
                            </item>
                        </item>
                    </item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

onepage.html

<!-- ko foreach: getRegion('componentDisplayArea') -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko-->

This works completely fine so far.
Now what I need but can't figure out is how to pass data from the server to my script.
To be more specific, I need an array of all items in the cart and their delivery status, as well as the current server time.
I know how I could pass parameters to the js when I am calling the js from a .phtml template since that's not the case here, how can I get the data in this scenario?

Update:

I need information on which products are in the cart and whether they are available or not.
We have products that we don't keep in stock, so thats what the estimated delivery time depends on.
Which is the goal of the uiComponent -> estimating delivery time.

Also I need some pre formatted and calculated timestamps, because I already have the logic working in php for another section of the page and figured, if I already have to pass server parameters to my uiComponent I might as well just transfer those as well so I dont have to rebuild the logic in js
(I've read somewhere that processing Dates and timezones in js might be messy because browsers handle it differently?! but i don't know how much of an issue that is actually)

Was it helpful?

Solution

It entirely depends on what data you need.

Your options are:

  • Use RequireJS for dependencies, for example Magento_Customer/js/model/customer for customer data or Magento_Checkout/js/model/quote for quote data.
  • If it's custom data you can use an Ajax request to retrieve it from a controller
  • Some core data is already available on the window object, you can use console.log(window) to check what's available. But be careful as this may not update on the fly, this is where the RequireJS dependencies noted above come in handy.
  • Add your custom data to the window object, this isn't ideal in my opinion but it does the job

Retrieving data from the JS model

This is how you can use the Quote Require JS module to retrieve data such as the shipping address.

define(
  [
    'Magento_Checkout/js/model/quote',
  ],
  function (quote) {
    'use strict';

    const shippingAddress = quote.shippingAddress();
    console.log(shippingAddress);
  }
);

Some other data returned by vendor/magento/module-checkout/view/frontend/web/js/model/quote.js. These are Knockout observables which is why we add parenthesis to get the value such as quote.shippingAddress().

        totals
        shippingAddress
        shippingMethod
        billingAddress
        paymentMethod
        guestEmail
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top