Skip to content

Magento2 Integrate UI component in Frontend

I am integrating UI grid with complete CRUD operations with UI component on frontend. But i am facing 1 issue of caching, when we edit from Actions column on frontend grid, the data provider is called and i get the loaded data only after i flush cache from terminal.

So if i edit a data from frontend grid, it gives the correct data and then i save the data. Now, again if i edit the same data, i get the old loaded data , not the recent one which i updated.

Below are my code –

File path : app/code/MageMango/SubUserAccount/Controller/Customer/Edit.php

    <?php
namespace MageMangoSubUserAccountControllerCustomer;

use MagentoFrameworkAppActionContext;
use MagentoFrameworkViewResultPageFactory;
use MageMangoSubUserAccountApiUserRepositoryInterface;
use MagentoFrameworkAppCacheTypeListInterface;
use MagentoFrameworkAppCacheFrontendPool;

class Edit extends MagentoFrameworkAppActionAction
{
    protected $cacheTypeList;

    protected $cacheFrontendPool;

    /**
     * @var MagentoFrameworkViewResultPageFactory
     */
    protected $resultPageFactory;

    /**
     * @var MageMangoCodFeeApiUserRepositoryInterface
     */
    protected $userRepository;

    /**
     * Edit constructor.
     *
     * @param Context $context
     * @param PageFactory $resultPageFactory
     * @param UserRepositoryInterface $userRepository
     */
    public function __construct(
        Context $context,
        PageFactory $resultPageFactory,
        UserRepositoryInterface $userRepository,
        TypeListInterface $cacheTypeList,
        Pool $cacheFrontendPool
    ) {
        parent::__construct($context);
        $this->resultPageFactory = $resultPageFactory;
        $this->userRepository = $userRepository;
        $this->cacheTypeList = $cacheTypeList;
        $this->cacheFrontendPool = $cacheFrontendPool;
    }
    /**
     * Default customer account page
     *
     * @return void
     */
    public function execute()
    {
        $cacheFrontendPool = $this->cacheFrontendPool;
        foreach ($cacheFrontendPool as $cacheFrontend) {
            $cacheFrontend->clean();
        }
        $writer = new Zend_Log_Writer_Stream(BP . '/var/log/abc4.log');
        $logger = new Zend_Log();
        $logger->addWriter($writer);
        $logger->info("tess");

        $id = $this->getRequest()->getParam('user_id');
        $model = $this->userRepository->getById($id);

        $resultPage = $this->resultPageFactory->create();
        /*$resultPage->getConfig()->getTitle()
            ->prepend($model->getUserId() ? $model->getUserName() : __('New User'));*/
        return $resultPage;
    }
}

File Path : app/code/MageMango/SubUserAccount/view/frontend/layout/subuseraccount_customer_edit.xml

    <?xml version="1.0" encoding="UTF-8"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
    <update handle="customer_account"/>
    <head>
        <title>Update User</title>
        <css src="MageMango_SubUserAccount::css/backend.css" />
    </head>
    <body>
        <referenceBlock name="page.main.title">
            <action method="setPageTitle">
                <argument translate="true" name="title" xsi:type="string">Update User</argument>
            </action>
        </referenceBlock>
        <referenceContainer name="content">
            <uiComponent name="subuser_form" />
        </referenceContainer>
    </body>
</page>

File Path : app/code/MageMango/SubUserAccount/view/frontend/ui_component/subuser_form.xml

    <?xml version="1.0" encoding="UTF-8"?>
<!--
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <argument name="data" xsi:type="array">
        <item name="js_config" xsi:type="array">
            <item name="provider" xsi:type="string">subuser_form.subuser_form_data_source</item>
        </item>
        <item name="config" xsi:type="array">
            <item name="deleteConfirmationMessage" translate="true" xsi:type="string">Are you sure you want to delete this address?</item>
        </item>
        <item name="label" xsi:type="string" translate="true">Update User</item>
        <item name="reverseMetadataMerge" xsi:type="boolean">true</item>
        <item name="template" xsi:type="string">templates/form/collapsible</item>
    </argument>
    <settings>
        <namespace>subuser_form</namespace>
        <ajaxSave>true</ajaxSave>
        <ajaxSaveType>simple</ajaxSaveType>
        <dataScope>data</dataScope>
        <deps>
            <dep>subuser_form.subuser_form_data_source</dep>
        </deps>
    </settings>
    <container name="button_set">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="formElement" xsi:type="string">container</item>
                    <item name="template" xsi:type="string">ui/form/components/complex</item>
                    <item name="label" xsi:type="null"/>
                </item>
            </argument>
            <container name="save_button" class="MageMangoSubUserAccountBlockEditUserSaveButton" component="MageMango_SubUserAccount/js/form/element/options">
                <argument name="data" xsi:type="array">
                    <item name="config" xsi:type="array">
                        <item name="formElement" xsi:type="string">container</item>
                        <item name="provider" xsi:type="null"/>
                        <item name="title" translate="true" xsi:type="string">Save User</item>
                    </item>
                </argument>
            </container>
        </container>
    <dataSource name="subuser_form_data_source">
        <argument name="data" xsi:type="array">
            <item name="js_config" xsi:type="array">
                <item name="component" xsi:type="string">Magento_Ui/js/form/provider</item>
            </item>
        </argument>
        <settings>
            <submitUrl path="subuseraccount/customer/saveuser"/>
        </settings>
        <dataProvider class="MageMangoSubUserAccountModelDataProvider" name="subuser_form_data_source">
            <settings>
                <requestFieldName>user_id</requestFieldName>
                <primaryFieldName>user_id</primaryFieldName>
            </settings>
        </dataProvider>
    </dataSource>

    <container name="messages" component="Magento_Ui/js/form/components/html">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="additionalClasses" xsi:type="string">message message-error</item>
                <item name="visible" xsi:type="boolean">false</item>
                <item name="imports" xsi:type="array">
                    <item name="responseData" xsi:type="string">${ $.parentName }:responseData</item>
                </item>
                <item name="listens" xsi:type="array">
                    <item name="responseData.error" xsi:type="string">visible</item>
                    <item name="responseData.messages" xsi:type="string">content</item>
                </item>
            </item>
        </argument>
    </container>
    <fieldset name="user_general">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="is_collection" xsi:type="boolean">true</item>
            </item>
        </argument>
        <settings>
            <label/>
            <dataScope/>
        </settings>

        <field name="user_id" formElement="input">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="classes" xsi:type="string">user_id</item>
                </item>
            </argument>
            <settings>
                <dataType>text</dataType>
                <elementTmpl>MageMango_SubUserAccount/form/element/input</elementTmpl>
                <visible>true</visible>
            </settings>
        </field>
        <field name="user_name" sortOrder="10" formElement="input">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="classes" xsi:type="string">user_name</item>
                    <item name="required" xsi:type="boolean">true</item>
                    <item name="notice" xsi:type="string" translate="true">
                        Enter Name
                    </item>
                    <item name="validation" xsi:type="array">
                        <item name="required-entry" xsi:type="boolean">true</item>
                        <item name="validate-no-html-tags" xsi:type="boolean">true</item>
                    </item>
                </item>
            </argument>
            <settings>
                <dataType>text</dataType>
                <label translate="true">Name</label>
                <dataScope>user_name</dataScope>
                <elementTmpl>MageMango_SubUserAccount/form/element/input</elementTmpl>
            </settings>
        </field>
        <field name="user_email" sortOrder="20" formElement="input">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="classes" xsi:type="string">user_email</item>
                </item>
            </argument>
            <settings>
                <label translate="true">Email</label>
                <dataType>text</dataType>
                <dataScope>user_email</dataScope>
                <validation>
                    <rule name="required-entry" xsi:type="boolean">true</rule>
                </validation>
                <elementTmpl>MageMango_SubUserAccount/form/element/input</elementTmpl>
            </settings>
        </field>
        <field name="status">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="classes" xsi:type="string">user_status</item>
                    <item name="sortOrder" xsi:type="number">30</item>
                    <item name="dataType" xsi:type="string">boolean</item>
                    <item name="formElement" xsi:type="string">checkbox</item>
                    <item name="prefer" xsi:type="string">toggle</item>
                    <item name="label" xsi:type="string" translate="true">Status</item>
                    <item name="valueMap" xsi:type="array">
                        <item name="true" xsi:type="number">1</item>
                        <item name="false" xsi:type="number">0</item>
                    </item>
                    <item name="valuesForOptions" xsi:type="array">
                        <item name="boolean" xsi:type="string">boolean</item>
                    </item>
                    <item name="dataScope" xsi:type="string">status</item>
                </item>
            </argument>
            <settings>
                <elementTmpl>MageMango_SubUserAccount/form/element/switcher</elementTmpl>
            </settings>
        </field>
    </fieldset>
</form>

File Path : app/code/MageMango/SubUserAccount/Model/DataProvider.php

    <?php
namespace MageMangoSubUserAccountModel;

use MageMangoSubUserAccountModelResourceModelUserCollectionFactory;

class DataProvider extends MagentoUiDataProviderAbstractDataProvider
{
    /**
     * Get Loaded data
     *
     * @var array
     */
    protected $loadedData;

    /**
     * DataProvider constructor.
     *
     * @param string $name
     * @param string $primaryFieldName
     * @param string $requestFieldName
     * @param CollectionFactory $userCollectionFactory
     * @param array $meta
     * @param array $data
     */
    public function __construct(
        $name,
        $primaryFieldName,
        $requestFieldName,
        CollectionFactory $userCollectionFactory,
        array $meta = [],
        array $data = []
    ) {
        $writer = new Zend_Log_Writer_Stream(BP . '/var/log/abc2.log');
        $logger = new Zend_Log();
        $logger->addWriter($writer);
        $logger->info("tesss2");

        $this->collection = $userCollectionFactory->create();
        parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data);
    }

    /**
     * Get Data
     *
     * @return array
     */
    public function getData()
    {
        $writer = new Zend_Log_Writer_Stream(BP . '/var/log/abc1.log');
        $logger = new Zend_Log();
        $logger->addWriter($writer);
        $logger->info("tesss");

        if (isset($this->loadedData)) {
            return $this->loadedData;
        }

        $items = $this->collection->getItems();

        foreach ($items as $item) {
            $writer = new Zend_Log_Writer_Stream(BP . '/var/log/abc.log');
            $logger = new Zend_Log();
            $logger->addWriter($writer);
            $logger->info(print_r($item->getData(), true));

            $userId = $item->getUserId();
            $this->loadedData[$userId] = $item->getData();
        }
        //exit();
        return $this->loadedData;
    }
}

You can see that i have added many logs to debug till where it is working but until i flush cache, none of the logs are working.

I assume i can use cacheble=false in layout but i dont think that is the correct way as it decreases performance.

Need expert help here please

Thank you