0

I am new to magento 2 and my magento version is 2.4. I am trying to show my custom grid on magento admin but, I get the following exception:

main.CRITICAL: Exception: Not registered handle faq_question_listing_data_source in /var/www/magento2ce/public/vendor/magento/framework/View/Element/UiComponent/DataProvider/CollectionFactory.php:49
Stack trace:

What I have done so far is create a menu item called "Frequently Asked Questions" under CONTENT/Elements. Clicking on it redirects me to the page where I want to show my admin grid. I am doing this through ui_components. My grid layout xml looks like following

<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<listing 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">faq_question_listing.faq_question_listing_data_source</item>
        </item>
    </argument>
    <settings>
        <buttons>
            <button name="add">
                <url path="*/*/new"/>
                <class>primary</class>
                <label translate="true">Add New Question</label>
            </button>
        </buttons>
        <spinner>faq_question_columns</spinner>
        <deps>
            <dep>faq_question_listing.faq_question_listing_data_source</dep>
        </deps>
    </settings>
    <dataSource name="faq_question_listing_data_source" component="Magento_Ui/js/grid/provider">
        <settings>
            <storageConfig>
                <param name="indexField" xsi:type="string">id</param>
            </storageConfig>
            <updateUrl path="mui/index/render"/>
        </settings>
        <aclResource>Magento_Cms::page</aclResource>
        <dataProvider class="FaqGridDataProvider" name="faq_question_listing_data_source">
            <settings>
                <requestFieldName>id</requestFieldName>
                <primaryFieldName>id</primaryFieldName>
            </settings>
        </dataProvider>
    </dataSource>
    <listingToolbar name="listing_top">
        <settings>
            <sticky>true</sticky>
        </settings>
        <bookmark name="bookmarks"/>
        <columnsControls name="columns_controls"/>
        <filterSearch name="fulltext"/>
        <filters name="listing_filters">
            <argument name="data" xsi:type="array">
                <item name="observers" xsi:type="array">
                    <item name="column" xsi:type="string">column</item>
                </item>
            </argument>
            <settings>
                <templates>
                    <filters>
                        <select>
                            <param name="template" xsi:type="string">ui/grid/filters/elements/ui-select</param>
                            <param name="component" xsi:type="string">Magento_Ui/js/form/element/ui-select</param>
                        </select>
                    </filters>
                </templates>
            </settings>
            <filterSelect name="store_id" provider="${ $.parentName }">
                <settings>
                    <captionValue>0</captionValue>
                    <options class="Magento\Cms\Ui\Component\Listing\Column\Cms\Options"/>
                    <label translate="true">Store View</label>
                    <dataScope>store_id</dataScope>
                    <imports>
                        <link name="visible">ns = ${ $.ns }, index = ${ $.index }:visible</link>
                    </imports>
                </settings>
            </filterSelect>
        </filters>
        <massaction name="listing_massaction">
            <action name="delete">
                <settings>
                    <confirm>
                        <message translate="true">Are you sure you want to delete selected items?</message>
                        <title translate="true">Delete items</title>
                    </confirm>
                    <url path="cms/page/massDelete"/>
                    <type>delete</type>
                    <label translate="true">Delete</label>
                </settings>
            </action>
            <action name="disable">
                <settings>
                    <url path="cms/page/massDisable"/>
                    <type>disable</type>
                    <label translate="true">Disable</label>
                </settings>
            </action>
            <action name="enable">
                <settings>
                    <url path="cms/page/massEnable"/>
                    <type>enable</type>
                    <label translate="true">Enable</label>
                </settings>
            </action>
            <action name="edit">
                <settings>
                    <callback>
                        <target>editSelected</target>
                        <provider>faq_question_listing.faq_question_listing.faq_question_columns_editor</provider>
                    </callback>
                    <type>edit</type>
                    <label translate="true">Edit</label>
                </settings>
            </action>
        </massaction>
        <paging name="listing_paging"/>
    </listingToolbar>
    <columns name="faq_question_columns">
        <settings>
            <editorConfig>
                <param name="clientConfig" xsi:type="array">
                    <item name="saveUrl" xsi:type="url" path="cms/page/inlineEdit"/>
                    <item name="validateBeforeSave" xsi:type="boolean">false</item>
                </param>
                <param name="indexField" xsi:type="string">id</param>
                <param name="enabled" xsi:type="boolean">true</param>
                <param name="selectProvider" xsi:type="string">faq_question_listing.faq_question_listing.faq_question_columns.ids</param>
            </editorConfig>
            <childDefaults>
                <param name="fieldAction" xsi:type="array">
                    <item name="provider" xsi:type="string">faq_question_listing.faq_question_listing.cms_page_columns_editor</item>
                    <item name="target" xsi:type="string">startEdit</item>
                    <item name="params" xsi:type="array">
                        <item name="0" xsi:type="string">${ $.$data.rowIndex }</item>
                        <item name="1" xsi:type="boolean">true</item>
                    </item>
                </param>
            </childDefaults>
        </settings>
        <selectionsColumn name="ids">
            <settings>
                <indexField>id</indexField>
                <resizeEnabled>false</resizeEnabled>
                <resizeDefaultWidth>55</resizeDefaultWidth>
            </settings>
        </selectionsColumn>
        <column name="id">
            <settings>
                <filter>textRange</filter>
                <label translate="true">ID</label>
                <sorting>asc</sorting>
            </settings>
        </column>
        <column name="Question">
            <settings>
                <filter>text</filter>
                <editor>
                    <validation>
                        <rule name="required-entry" xsi:type="boolean">true</rule>
                    </validation>
                    <editorType>text</editorType>
                </editor>
                <label translate="true">Question</label>
            </settings>
        </column>
        <column name="Status">
            <settings>
                <filter>text</filter>
                <editor>
                    <validation>
                        <rule name="required-entry" xsi:type="boolean">true</rule>
                    </validation>
                    <editorType>text</editorType>
                </editor>
                <label translate="true">Status</label>
            </settings>
        </column>
        <column name="page_layout" component="Magento_Ui/js/grid/columns/select">
            <settings>
                <options class="Magento\Cms\Model\Page\Source\PageLayout"/>
                <filter>select</filter>
                <editor>
                    <editorType>select</editorType>
                </editor>
                <dataType>select</dataType>
                <label translate="true">Layout</label>
            </settings>
        </column>
        <column name="Status" class="Magento\Store\Ui\Component\Listing\Column\Store">
            <settings>
                <label translate="true">Store View</label>
                <bodyTmpl>ui/grid/cells/html</bodyTmpl>
                <sortable>false</sortable>
            </settings>
        </column>
        <column name="is_active" component="Magento_Ui/js/grid/columns/select">
            <settings>
                <options class="Magento\Cms\Model\Page\Source\IsActive"/>
                <filter>select</filter>
                <editor>
                    <editorType>select</editorType>
                </editor>
                <dataType>select</dataType>
                <label translate="true">Status</label>
            </settings>
        </column>
        <column name="creation_time" class="Magento\Ui\Component\Listing\Columns\Date" component="Magento_Ui/js/grid/columns/date">
            <settings>
                <filter>dateRange</filter>
                <dataType>date</dataType>
                <label translate="true">Created</label>
            </settings>
        </column>
        <column name="custom_theme_from" class="Magento\Ui\Component\Listing\Columns\Date" component="Magento_Ui/js/grid/columns/date">
            <settings>
                <timezone>false</timezone>
                <dateFormat>MMM d, y</dateFormat>
                <filter>dateRange</filter>
                <editor>
                    <editorType>date</editorType>
                </editor>
                <dataType>date</dataType>
                <label translate="true">Custom design from</label>
                <visible>false</visible>
            </settings>
        </column>
        <column name="custom_root_template" component="Magento_Ui/js/grid/columns/select">
            <settings>
                <options class="Magento\Cms\Model\Page\Source\CustomLayout"/>
                <filter>select</filter>
                <editor>
                    <editorType>select</editorType>
                </editor>
                <dataType>select</dataType>
                <label translate="true">Custom Layout</label>
                <visible>false</visible>
            </settings>
        </column>
        <column name="meta_title">
            <settings>
                <filter>text</filter>
                <editor>
                    <editorType>text</editorType>
                </editor>
                <label translate="true">Meta Title</label>
                <visible>false</visible>
            </settings>
        </column>
        <column name="meta_keywords">
            <settings>
                <filter>text</filter>
                <editor>
                    <editorType>text</editorType>
                </editor>
                <label translate="true">Meta Keywords</label>
                <visible>false</visible>
            </settings>
        </column>
        <column name="meta_description">
            <settings>
                <filter>text</filter>
                <editor>
                    <editorType>text</editorType>
                </editor>
                <label translate="true">Meta Description</label>
                <visible>false</visible>
            </settings>
        </column>
        <actionsColumn name="actions" class="Magento\Cms\Ui\Component\Listing\Column\PageActions">
            <settings>
                <indexField>id</indexField>
                <resizeEnabled>false</resizeEnabled>
                <resizeDefaultWidth>107</resizeDefaultWidth>
            </settings>
        </actionsColumn>
    </columns>
</listing>

My di.xml file is under app\code<Vendor><component>\etc\di.xml and looks like the following:

<?xml version="1.0" encoding="utf-8" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\Faq\Api\QuestionRepositoryInterface" type="Examples\FirstModule\Model\QuestionRepository" />
    <preference for="Magento\Faq\Api\Data\QuestionInterface" type="Magento\Faq\Model\Question" />
    <preference for="Magento\Faq\Api\Data\QuestionSearchResultsInterface" type="Magento\Framework\Api\SearchResults" />

    <type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
        <arguments>
            <argument name="collections" xsi:type="array">
                <item name="magebit_faq_question_listing_data_source"
                      xsi:type="string">Magebit\Faq\Model\ResourceModel\Question\Collection</item>
            </argument>
        </arguments>
    </type>
    <virtualType name="Magebit\Faq\Model\ResourceModel\Question\Grid\Collection"
                 type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
        <arguments>
            <argument name="mainTable" xsi:type="string">Magebit_Faq_Question</argument>
            <argument name="resourceModel" xsi:type="string">
                Magebit\Faq\Model\ResourceModel\Question
            </argument>
        </arguments>
    </virtualType>
    <virtualType name="FaqGridFilterPool"
                 type="Magento\Framework\View\Element\UiComponent\DataProvider\FilterPool">
        <arguments>
            <argument name="appliers" xsi:type="array">
                <item name="regular" xsi:type="object">
                    Magento\Framework\View\Element\UiComponent\DataProvider\RegularFilter
                </item>
                <item name="fulltext" xsi:type="object">
                    Magento\Framework\View\Element\UiComponent\DataProvider\FulltextFilter
                </item>
            </argument>
        </arguments>
    </virtualType>

    <virtualType name="FaqGridDataProvider"
                 type="Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider">
        <arguments>
            <argument name="collection" xsi:type="object" shared="false">
                Magebit\Faq\Model\ResourceModel\Question\Collection
            </argument>
            <argument name="filterPool" xsi:type="object" shared="false">
                FaqGridFilterPool
            </argument>
        </arguments>
    </virtualType>
    <virtualType name="Magebit\Faq\Indexer\FaqIndexerHandlerVirtual"
                 type="Divante\VsbridgeIndexerCore\Indexer\GenericIndexerHandler">
        <arguments>
            <argument name="indexIdentifier" xsi:type="string">vue_storefront_catalog</argument>
            <argument name="typeName" xsi:type="string">faq</argument>
        </arguments>
    </virtualType>

    <type name="Magebit\Faq\Model\Indexer\Question">
        <arguments>
            <argument name="indexerHandler" xsi:type="object">Magebit\Faq\Indexer\FaqIndexerHandlerVirtual</argument>
        </arguments>
    </type>
</config>

The controller file for this grid layout is under the following dir, app\code<Vendor><component>\Controller\Adminhtml\Question\Index.php and it looks like below:

<?php

namespace Magebit\Faq\Controller\Adminhtml\Question;

use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;

class Index extends Action
{
    /**
     * @var \Magento\Framework\View\Result\PageFactory
     */
    protected $resultPagefactory;

    /**
     *
     * @param \Magento\Backend\App\Action\Context $context
     * @param \Magento\Framework\View\Result\PafeFactory $resultPageFactory
     */

    public function __construct(Context $context, PageFactory $resultPageFactory)
    {
        parent::__construct($context);
        $this->resultPagefactory = $resultPageFactory;
    }

    /**
     * Load the page defined in view\adminhtml\layout\faq_question_index.xml
     *
     * @return \Magento\Framework\View\result\Page
     */

    public function execute()
    {
        $resultPage = $this->resultPagefactory->create();
//        $resultPage->setActiveMenu("Magento_Backend::content_elements");
        $resultPage->getConfig()->getTitle()->prepend('Frequently Asked Questions');
        return $resultPage;
    }
}

Now what I do not understand is that, Why am I getting that exception? How do I register my datasource for my grid layout?

1 Answer 1

0

It's a some mess in your di.xml and extra logic.

You can simplify and use Resource Model, you just need to create virtual Grid Collection (Search Result) and define it in CollectionFactory

<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <!-- ... -->
    <virtualType name="Magebit\Faq\Model\ResourceModel\Question\Grid\Collection"
                 type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
        <arguments>
            <argument name="mainTable" xsi:type="string">Magebit_Faq_Question</argument>
            <argument name="resourceModel" xsi:type="string">Magebit\Faq\Model\ResourceModel\Question</argument>
        </arguments>
    </virtualType>

    <type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
        <arguments>
            <argument name="collections" xsi:type="array">
                <item name="faq_question_listing_data_source"
                      xsi:type="string">Magebit\Faq\Model\ResourceModel\Question\Grid\Collection</item>
            </argument>
        </arguments>
    </type>

To be sure that Magebit_Faq_Question is correct table name in your DB.

In your listing should be

    <!-- ... -->
    <dataProvider class="Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider" name="faq_question_listing_data_source">
    <!-- ... -->

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.