Back to Top

How to create custom Js window configProviders in Magento 2

Updated 23 February 2024

Here i am going to explain,

How to create custom Js window configProviders as Magento’s window.checkoutConfig provider.

In Magento 2 all required data saved in window.checkoutConfig
so at the time of checkout it can be fetched by js models easily.
We can also save our custom required data in window.checkoutConfig providers by using frontend/di.xml

Here is an image, see how data stored in window.checkoutConfig.

So, now lets create our own Config Provider, we can use it in our Module as well as in dependent Modules.

1. Create di.xml file Webkul/Knockout/etc/frontend/di.xml

Searching for an experienced
Magento 2 Company ?
Find out More
<?xml version="1.0"?>
<!-- 
/**
 * Webkul Software.
 *
 * @category  Webkul
 * @package   Webkul_Knockout
 * @author    Webkul
 * @copyright Webkul Software Private Limited (https://webkul.com)
 * @license   https://store.webkul.com/license.html
 */
 -->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Webkul\Knockout\Model\CustomConfigProvider">
        <arguments>
            <argument name="configProviders" xsi:type="array">
                <item name="custom_config_provider" xsi:type="object">Webkul\Knockout\Model\DefaultConfigProvider</item>
            </argument>
        </arguments>
    </type>
</config>

2. Now create Config Provider Interface Webkul/Knockout/Model/ConfigProviderInterface.php

<?php
/**
 * Webkul Software.
 *
 * @category  Webkul
 * @package   Webkul_Knockout
 * @author    Webkul
 * @copyright Webkul Software Private Limited (https://webkul.com)
 * @license   https://store.webkul.com/license.html
 */
namespace Webkul\Knockout\Model;

/**
 * Interface ConfigProviderInterface
 * @api
 */
interface ConfigProviderInterface
{

    /**
     * Retrieve assoc array of checkout configuration
     *
     * @return array
     */
    public function getConfig();
}

3. Create Webkul\Knockout\Model\CustomConfigProvider.php which will be used to
collect all Child Config Providers data and merge them.

<?php
/**
 * Webkul Software.
 *
 * @category  Webkul
 * @package   Webkul_Knockout
 * @author    Webkul
 * @copyright Webkul Software Private Limited (https://webkul.com)
 * @license   https://store.webkul.com/license.html
 */
namespace Webkul\Knockout\Model;

class CustomConfigProvider implements ConfigProviderInterface
{
    /**
     * @var ConfigProviderInterface[]
     */
    private $configProviders;

    /**
     * @param ConfigProviderInterface[] $configProviders
     */
    public function __construct(
        array $configProviders
    ) {
        $this->configProviders = $configProviders;
    }

    /**
     * @inheritdoc
     */
    public function getConfig()
    {
        $config = [];
        foreach ($this->configProviders as $configProvider) {
            $config = array_merge_recursive($config, $configProvider->getConfig());
        }
        return $config;
    }
}

Now see in the di.xml file, we have passed a DefaultConfigProvider as an argument for CustomConfigProvider.

4. Finally Create Webkul/Knockout/Model/DefaultConfigProvider.php

<?php
/**
 * Webkul Software.
 *
 * @category  Webkul
 * @package   Webkul_Knockout
 * @author    Webkul
 * @copyright Webkul Software Private Limited (https://webkul.com)
 * @license   https://store.webkul.com/license.html
 */
namespace Webkul\Knockout\Model;

class DefaultConfigProvider implements ConfigProviderInterface
{
    /**
     * @inheritdoc
     */
    public function getConfig()
    {
        $config = [
            'name' => 'John Doe',
            'Email' => '[email protected]',
            'DOB' => '08/05/1990',
        ];

        return $config;
    }
}

Example: how to use our custom js provider.

I am going to call our custom phtml file on customer account, you call according to your requirement.

a) Create Webkul/Knockout/view/frontend/layout/knockout_account_index.xml

<?xml version="1.0"?>

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <update handle="customer_account"/>
    <body>
        <referenceContainer name="content">
            <block class="Webkul\Knockout\Block\Account" name="customer_account_knockout_test" template="Webkul_Knockout::account/knockout.phtml" cacheable="false">
                <arguments>
                    <argument name="jsLayout" xsi:type="array">
                        <item name="components" xsi:type="array">
                            <item name="customcomponent" xsi:type="array">
                                <item name="component" xsi:type="string">Webkul_Knockout/js/custom-component</item>
                            </item>
                        </item>
                    </argument>
                </arguments>
            </block>
        </referenceContainer>
    </body>
</page>

In this xml, i have load out phtml file knockout.phtml with Block Webkul\Knockout\Block\Account

And what about other things in this xml file ? I already explained about it blog: How to Intialize Js Component Using Layout XML in Magento2 , you can read it.

b) Ok, now create knockout.phtml and Block Webkul\Knockout\Block\Account.
Phtml file: Webkul/Knockout/view/frontend/templates/account/knockout.phtml

<script>
    window.customConfig = <?php /* @escapeNotVerified */ echo \Zend_Json::encode($block->getCustomConfig()); ?>;
</script>

<div id="custom-component" data-bind="scope:'customcomponent'">
    <!-- ko template: getTemplate() --><!-- /ko -->
    <script type="text/x-magento-init">
    {
        "#custom-component": {
            "Magento_Ui/js/core/app":  <?php /* @escapeNotVerified */ echo $block->getJsLayout();?>
        }
    }
    </script>
</div>

Block File: Webkul/Knockout/Block/Account.php

<?php
/**
 * Webkul Software.
 *
 * @category  Webkul
 * @package   Webkul_Knockout
 * @author    Webkul
 * @copyright Webkul Software Private Limited (https://webkul.com)
 * @license   https://store.webkul.com/license.html
 */
namespace Webkul\Knockout\Block;

class Account extends \Magento\Framework\View\Element\Template
{
    /**
     * @var array
     */
    protected $jsLayout;

    /**
     * @var \Webkul\Knockout\Model\CustomConfigProvider
     */
    protected $configProvider;

    /**
     * @param \Magento\Framework\View\Element\Template\Context $context
     * @param array $data
     */
    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        \Webkul\Knockout\Model\CustomConfigProvider $configProvider,
        array $data = []
    ) {
        parent::__construct($context, $data);
        $this->jsLayout = isset($data['jsLayout']) && is_array($data['jsLayout']) ? $data['jsLayout'] : [];
        $this->configProvider = $configProvider;
    }

    /**
     * @return string
     */
    public function getJsLayout()
    {
        return \Zend_Json::encode($this->jsLayout);
    }

    public function getCustomConfig()
    {
        return $this->configProvider->getConfig();
    }
}

Now refresh the page, and press F12 find for our window.customConfig

You will see,
configproviders

How we can use data from window.customConfig?
Here is an another example.

As you can see i have loaded js component as well on our knockout.phtml file.

So let’s create Webkul/Knockout/view/frontend/web/js/custom-component.js

define([
    'jquery',
    'uiComponent',
    'ko',
    ], function ($, Component, ko) {
        'use strict';
        var customData = window.customConfig;
        return Component.extend({
            defaults: {
                template: 'Webkul_Knockout/knockout-test'
            },

            initialize: function () {
                this._super();
                console.log(customData);
            },
        });
    }
);

Open Console and check, you will see the data as object.
console-data

You can have your own custom code in the Webkul/Knockout/view/frontend/web/template/knockout-test.html file. As an example, you can check the following code:

<div class="component-wrapper">
    <div data-bind="text: 'Knockout Works'"></div>
</div>

That’s It.

I hope it will help you to create Js Based Project.

Thanks.

. . .

Leave a Comment

Your email address will not be published. Required fields are marked*


2 comments

  • POYIIZ
    • Akash Panwar (Moderator)
  • Back to Top

    Message Sent!

    If you have more details or questions, you can reply to the received confirmation email.

    Back to Home