4

I'm trying to access some data stored in the Magento_Customer/js/customer-data object

I have the following files:

--- garage.js ---

define([
   'Magento_Customer/js/customer-data'
], function(customerData){
    'use strict';
    return {
        getCustomerName: function(){
            return customerData.get("garage")();
        }
    }
});

-- sidebar.phtml --

<script type="text/javascript">
    require(['Revival_Garage/js/view/garage'], function(garage){
        console.log("--");
        console.log(garage.getCustomerName());
        console.log("--");
        // document.getElementById("customer_garage").innerHTML = garage.getCustomerName();
    });
</script>
<span id="customer_garage">
</span>

When the page loads and my JavaScript automatically executes, my console has the following output:

enter image description here

Which, obviously isn't quite what I was hoping for.

If i run the same exact code in my console once the page is totally loaded, I get this:

enter image description here

Which does have the data I expect.

Why is it that I can't access this data on page load?

I don't see any mention anywhere in any of the documentation for customer-data stating I need to run my js any specific way (eg. waiting on DOM load)

Am I missing something?

Relevant pages I could find, documentation-wise

Magento2 StackExchange:
Magento 2: how do customer sections / sections.xml work?

Alan Storm's blog Understanding the limitations of sections.xml

In My own troubleshooting I found out requirejs has a domReady plugin you can use, so i also tried to add 'domReady!' to my define call. which yielded the same results as above.


EDIT: I figured it out by modifying my sidebar.phtml to use Knockout uicomponents. this page helped me a TON

5

TL;DR code for this:

-- sidebar.phtml --

<script type="text/x-magento-init">
   {"#garageElement": {"Magento_Ui/js/core/app": <?php echo $block->getJsLayout(); ?>}}
</script>

<div data-bind="scope: 'garage'" id="garageElement">
    <span data-bind="text: garageData().customer_name"></span>
</div>

-- module's layout.xml --

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="sidebar.additional">
            <block class="Revival\Garage\Block\Garage" name="revival.garage.knockout.sidebar" template="Revival_Garage::sidebar.phtml" after="wishlist_sidebar">
                <arguments>
                    <argument name="jsLayout" xsi:type="array">
                        <item name="components" xsi:type="array">
                            <item name="garage" xsi:type="array">
                                <item name="component" xsi:type="string">Revival_Garage/js/view/garage</item>
                            </item>
                        </item>
                    </argument>
                </arguments>
            </block>
        </referenceBlock>
    </body>
</page>

-- garage.js --

define([
    'uiComponent',
    'Magento_Customer/js/customer-data'
], function(component, customerData){
    'use strict';
    return component.extend({
        initialize: function(){
            this._super();
            this.garageData = customerData.get("garage");
        }
    });
});

Nothing else had to be changed, code wise, it was all frontend stuff as the backend code always worked. Hope this post helps someone googling for this in the future.

| improve this answer | |
  • very usefull, thx! – LucScu Feb 21 '18 at 17:29
5

For the people who come future, you can use subscribe function to wait for the object to load. So if anything changes in the object it will execute the function inside it.

        this.garage = customerData.get('garage');
        this.garage.subscribe(function () {
              console.log("--");
              console.log(garage.getCustomerName());
              console.log("--");
        }, this);

This will really help you to wait for cart information of the local storage.

| improve this answer | |
  • it works, but it won't update knockout text binding this way, because knockout will not wait for data to load – TheKitMurkit Nov 24 '19 at 15:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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