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

2 Answers 2

7

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.

2
  • it works, but it won't update knockout text binding this way, because knockout will not wait for data to load Nov 24, 2019 at 15:21
  • This is a great way to know if it's set but not great to know if it's not set as the function only fires if the value is set. May 10, 2021 at 20:04
6

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.

1
  • very usefull, thx!
    – LucScu
    Feb 21, 2018 at 17:29

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.