It happens that you are frequently facing asynchronous customer data loading while working with Magento 2. For example cart reloading, checkout, logging and user log in and some others are working through AJAX. In order to work with these data, Magento development team provides with a proper interface, that we are going to overview now.
Interface of the current module consists of js-module, which is uploaded by RequireJs and from backend interface that allows sending data by AJAX. Let’s consider a template for name displaying in default Magento 2 theme.
Customer’s name is displayed by this code implemented:
1 |
<span data-bind="text: new String('<?php echo $block->escapeHtml(__('Welcome, %1!', '%1'));?>').replace('%1', customer().firstname)"> |
As you can see in the following code the template is replaced by customer().firstname object property. And in the code below, you will see what customer object is related to:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<script type="text/x-magento-init"> { "*": { "Magento_Ui/js/core/app": { "components": { "customer": { "component": "Magento_Customer/js/view/customer" } } } } } </script> |
You can find out more about js-scripts and modules connection syntax in the following article: “JavaScript Integration Tips in Magento 2“.
As you can see, customer object is created in Magento_Customer/js/view/customer.js file:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
define([ 'uiComponent', 'Magento_Customer/js/customer-data' ], function (Component, customerData) { 'use strict'; return Component.extend({ initialize: function () { this._super(); this.customer = customerData.get('customer'); } }); }); |
It follows that the current code returns Component object (the definition of uiComponent we will cover in the next article) with overridden initialize method. All the magic of data uploading from server is performed right in this method. Please pay your attention at the string:
1 |
this.customer = customerData.get('customer'); |
Where customerData is a RequireJs module and it’s been initialized in Magento_Customer/js/customer-data.js.
Here is what we know at the moment: information about customers data we are getting from customerData.get(‘customer’) object. And we can transfer not only “customer”, but other parameters as well into get method.
But then we have a few questions regarding customerData use:
- where to get data
- what parameters could be transferred into customerData.get();
- is it possible to add your own parameters into customerData.get();
So, let’s consider all of them one after another.
If you enable debug mode in your browser and try to add a product to the cart, then you will notice a pretty usual behavior: there are several AJAX queries are sent to a server. But if you reload the page, you will see that initially the cart is empty, but during the page is being loaded the cart will be reloaded and all the previously added products will appear in it. This cart behavior tells us about asynchronous cart data loading, after the main page is loaded.
Magento Webdesign
Take your online store to the next level with BelVG Magento Webdesign
Visit the pageHowever, if you enable debugger you probably won’t see AJAX queries to the server. But we just saw that data was uploaded from somewhere, and please don’t forget that data should not come with the main page, because it may cause problems with enabled FPC. Basically, we are getting a conclusion that data should be uploaded from somewhere, but definitely not from AJAX. So we might think that they are stored in a browser. And it’s true.
If you take a look at Application->Local Storage (for Chrome browser) tab you will see these data:
Please take a look at “mage-cache-storage” section. All the data that can be used in customerData objects are stored in the particular section. If you delete this section and then reload a page, you will notice that all products in a cart are gone. And they will appear only in case you reload the current section one more time and add one more product to the cart.
Mage-cache-storage section structure is a regular JSON object, on which upper level we have a name of parameter, that we can transfer to get method of customerData object. Thus we finally handled with a structure of customerData, but we still have a question: from where all these data appeared in a browser, and what code is related to these data.
If you add one more product to the cart, you’ll be able to see such server query:
1 |
https://url_base/customer/section/load/?sections=cart%2Cmessages&update_section_id=true&_=1478514106235 |
As it follows from URL, we address to Magento\Customer\Controller\Section\Load controller with such parameters: sections=cart%2Cmessages&update_section_id=true. That is a controller we need, and it’s responsible for data update. In such manner we are able to update any sections.
Also, you can create a section on your own and use it according to your needs. You just have to register your section, by the following manipulations in di.xml file:
1 2 3 4 5 6 7 |
<type name="Magento\Customer\CustomerData\SectionPoolInterface"> <arguments> <argument name="sectionSourceMap" xsi:type="array"> <item name="your_module_data" xsi:type="string">\YourCompany_YourModule\Order\Plugin\Section</item> </argument> </arguments> </type> |
In the following code, the class \YourCompany_YourModule\Order\Plugin\Section should perform Magento\Customer\CustomerData\SectionSourceInterface interface. So now it’s really easy to get an access to the required information:
1 2 |
var dataObject = customerData.get('your_module_data'); var data = dataObject(); |
dataObject – it is the object, that returns ko.observable() method, so it’s rather easy to embed this object into knokountJs templates. Just execute the following command, to update data in browser storage for a certain section:
1 |
customerData.reload(['your_module_data'])) |
CustomerData provides with several very useful methods for data processing, let’s specify them:
- get(section) – please see above;
- set(section,data) – data inserting;
- reload(sections) – data reload;
- invalidate(section) – puts a remark about invalid data, and that is necessary to reload them.
Partner With Us
Let's discuss how to grow your business. Get a Free Quote.It’s all fine until this moment, but a problem with data validity managing appeared because we perform many operations, that are trying to modify data all the time. So we should control these data. One of the possible solution – is to hang an event on the actions, connected with changes. But don’t you think it’s very tiresome and errors search takes too much time. For this reason, Magento Development Team invented a very original method of data validity control. Let’s take a look more in details at Magento_Customer/js/customer-data.js file (this is the module, that initializes customerData), more specifically at these strings:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
$(document).on('ajaxComplete', function (event, xhr, settings) { var sections, redirects; if (settings.type.match(/post|put/i)) { sections = sectionConfig.getAffectedSections(settings.url); if (sections) { customerData.invalidate(sections); redirects = ['redirect', 'backUrl']; if (_.isObject(xhr.responseJSON) && !_.isEmpty(_.pick(xhr.responseJSON, redirects))) { return; } customerData.reload(sections, true); } } }); |
Magento Development Services
Take your online store to the next level with BelVG Magento development
Visit the pageAs you can see there is a function, hanged on ajaxComplete event in document object, and this function constantly compares URL address and that’s why URL selects those sections that should be updated. It’s a very useful mechanism of data validity control. We can add some sections, that will be updated upon transition to a certain URL. For that purpose we should add sections.xml file to etc/frontend directory in our module:
1 2 3 4 5 6 7 |
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Customer:etc/sections.xsd"> <action name="braintree/paypal/placeOrder"> <section name="cart"/> <section name="checkout-data"/> </action> </config> |
This example we got from braintree module and we notice, that cart section and checkout-data section will be overloaded after AJAX-query (post, put) with URL address braintree/paypal/placeOrder is executed. It stands to mention that there are sections, like message, that are being updated upon request for any URL, that’s why when you use ajax-queries in your modules, bear in mind that except of your request, at least one more will be executed, which will update sections. You can use GET method instead of POST, to escape this. In spite of seeming complexity, after you mastered it, you are getting very flexible tool for data and ajax-queries management.
Turn to BelVG development company and get a full range of Magento development services from ecommerce specialists.
Hi Jitesh,
You can find this field in this file \Magento\Customer\CustomerData\Section\Identifier::SECTION_KEY, and magento itself adds this field. To change value of this field you should do \Magento\Customer\CustomerData\SectionPoolInterface::getSectionsData($sectionsname, true)
There is a “data_id
:
1529480578”
, from where it is setting – data_id
How can we change the value ?
Pooja, thank you! Subscribe to our blog to stay tuned :)
Thank you so much for writing such informative and easy to understand article. I could have never understood this concept without this. Best wishes!
This article is wonderful! Thank you so much.