0

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)

1 Answer 1

0

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
3
  • I updated some more information on the needed data in my question. Both is custom data but assuming I can get the information on delivery status from the quote model I guess I could also just rebuild the time calculation in JS, so that would leave me with the requireJS dependency solution. Any chance you could give me another hint on how to add the model as a dependency and retrieve data from it? I've never done it before.
    – Chaz
    Commented Jan 15, 2021 at 18:02
  • I guess I could also just do an Ajax Request that retrieves the data from an controlloer which uses the php logic I already have, but wouldn't it be better to not have that extra query if it's not necessary?
    – Chaz
    Commented Jan 15, 2021 at 18:06
  • I've just updated my answer with an example. Yeah the checkout is slow enough so adding more requests isn't the best idea if it can be avoided. Although on the flip side if there are already 400+ network requests 1 more won't make much difference xD
    – Ben Crook
    Commented Jan 18, 2021 at 10:51

Your Answer

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

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