I'm trying to add a message in the minicart, but:
- The message depends on some external API calls I have to make at page load
- I can't figure out how to pass data to my UI component when it's inserted within the
jsLayout
argument of a block in a page layout
Note that I'm new to Magento, but I've made a lot of research and can't figure out what I need to do.
Hopefully I haven't missed anything obvious...
What works
I managed to get a "static" message at the correct position in the minicart by doing the following:
/view/frontend/layout/default.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="minicart">
<arguments>
<argument name="jsLayout" xsi:type="array">
<item name="components" xsi:type="array">
<item name="minicart_content" xsi:type="array">
<item name="children" xsi:type="array">
<item name="extra_info" xsi:type="array">
<item name="children" xsi:type="array">
<item name="minicart.message" xsi:type="array">
<item name="component" xsi:type="string">Module/js/view/checkout/minicart/message</item>
<item name="config" xsi:type="array">
<item name="template" xsi:type="string">Module/checkout/minicart/message</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</argument>
</arguments>
</referenceBlock>
</body>
</page>
/view/frontend/web/js/view/checkout/minicart/message.js
define(
[
'uiComponent',
],
function (
Component,
) {
'use strict';
/** Add view logic here if needed */
return Component.extend({
initialize: function() {
this._super();
this.message = 'OKAY';
}
});
}
);
/view/frontend/web/template/checkout/minicart/message.html
<div>
<span data-bind="text: message"></span>
</div>
"OKAY" displays correctly below the cart totals:
What I'm looking for
I'd like message
to be dependent on some API calls I have to make from the backend.
From what I understand, I could do that by using a DataProvider.
I have created the following DataProvider:
namespace Module\Model\Ui\MiniCart\Message;
use Magento\Ui\DataProvider\AbstractDataProvider;
class DataProvider extends AbstractDataProvider
{
public function getData()
{
return ['data' => ['message' => 'My dynamic message']];
}
}
And that's basically where I'm stuck. The dev docs linked above mention implementing the getDataSourceData()
in the "UI component’s PHP class" to return $this->getContext()->getDataProvider()->getData()
.
All of this implies that my UI component has been defined within <Module>/view/frontend/ui_component/message.xml
and included in the page layout using <uiComponent name="message"/>
, which is not the case.
I have tried creating the ui_component/message.xml
to add a component definition in there, but it's not being picked up (I checked by adding an invalid <invalidTag/>
in it, which did not throw any error).
I have tried adding <item>
tags to my default.xml
layout:
<item name="minicart.message" xsi:type="array">
<item name="component" xsi:type="string">Module/js/view/checkout/minicart/message</item>
<item name="provider" xsi:type="string">Module\Model\Ui\MiniCart\Message\DataProvider</item>
<item name="config" xsi:type="array">
<item name="template" xsi:type="string">Module/checkout/minicart/message</item>
</item>
</item>
But this doesn't work either, as I guess within the jsLayout
definition Magento doesn't pick up any PHP object anymore and the data is just passed on to the UI component directly (?).
I also tried to provide a more "generic" component name such as Module/message
and no other config, in the hope Magento would try to resolved the component via the ui_component/message.xml
, but to no avail.
I'm obviously lost here and I'm left wondering, how can I:
- Make a call to an external API
- Decide which message should be displayed based on API response
- Display this message in the minicart
Thanks for your help!