2

I have a basic CRUD repository setup, however when I try to go to the Admin Grid UI Component, the spinner just spins and nothing loads. No errors displayed in any of the logs either. When I inspect and view the XHR requests, I can see the collection loading (shark_id: 1, name: foo, etc.)

I'm also able to successfully view the collection on the frontend using a controller with:

$sharks = $this->sharkRepository->getList($this->searchCriteriaBuilder->create())->getItems();

So I know that it is possible to get the collection, but I'm at a loss as to why the Admin Grid won't load. I've gone over the naming and everything seems correct for the column names. Is there something I'm missing?

(Mostly full repository, all files relevant to the Model, ResourceModel, API, and so on are in this git repository)

Model:

<?php
namespace Practice\Sharks\Model;
use Magento\Framework\Model\AbstractModel;
use Magento\Framework\DataObject\IdentityInterface;
use Practice\Sharks\Api\Data\SharkInterface;
/**
 * Class Shark
 * @package Practice\Sharks\Model;
 */
class Shark extends AbstractModel implements SharkInterface, IdentityInterface
{

const CACHE_TAG = 'practice_sharks_shark';
/**
 *
 */
protected function _construct()
{
    $this->_init('Practice\Sharks\Model\ResourceModel\Shark');
}
/**
 * Get shark_id
 * @return string|null
 */
public function getId()
{
    return $this->getData(self::SHARK_ID);
}
/**
 * Set shark_id
 * @param string $sharkId
 * @return \Practice\Sharks\Api\Data\SharkInterface
 */
public function setId($sharkId)
{
    return $this->setData(self::SHARK_ID, $sharkId);
}
/**
 * @return mixed
 */
public function getName()
{
    return $this->getData(self::NAME);
}
/**
 * @param string $name
 */
public function setName($name)
{
    $this->setData(self::NAME, $name);
}
/**
 * @return mixed
 */
public function getCreatedAt()
{
    return $this->getData(self::CREATED_AT);
}
/**
 * @param string $createdAt
 */
public function setCreatedAt($createdAt)
{
    $this->setData(self::CREATED_AT, $createdAt);
}
/**
 * @return mixed
 */
public function getModifiedAt()
{
    return $this->getData(self::MODIFIED_AT);
}
/**
 * @param string $modifiedAt
 */
public function setModifiedAt($modifiedAt)
{
    $this->setData(self::MODIFIED_AT, $modifiedAt);
}
/**
 * Return unique ID(s) for each object in system
 *
 * @return string[]
 */
public function getIdentities()
{
    return [self::CACHE_TAG . '_' . $this->getId()];
}

}

ResourceModel

<?php
namespace Practice\Sharks\Model\ResourceModel;
/**
 * @package Practice\Sharks\Model\ResourceModel
 */
class Shark extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
{
    protected $_idFieldName = 'shark_id';
    /**
     *
     */
    protected function _construct()
    {
        $this->_init('practice_sharks', 'shark_id');
    }
}

Collection:

<?php
namespace Practice\Sharks\Model\ResourceModel\Shark;
/**
 */
class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
{
    /**
     *
     */
    protected function _construct()
    {
        $this->_init('Practice\Sharks\Model\Shark', 'Practice\Sharks\Model\ResourceModel\Shark');
    }
}

di.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">

<preference for="Practice\Sharks\Api\SharkRepositoryInterface" type="Practice\Sharks\Model\SharkRepository"/>
<preference for="Practice\Sharks\Api\Data\SharkInterface" type="Practice\Sharks\Model\Shark"/>
<preference for="Practice\Sharks\Api\Data\SharkSearchResultsInterface" type="Magento\Framework\Api\SearchResults"/>

<virtualType name="Practice\Sharks\Model\ResourceModel\Shark\Grid\Collection" type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
    <arguments>
        <argument name="mainTable" xsi:type="string">practice_sharks</argument>
        <argument name="resourceModel" xsi:type="string">Practice\Sharks\Model\ResourceModel\Shark\Collection</argument>
    </arguments>
</virtualType>

<type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
    <arguments>
        <argument name="collections" xsi:type="array">
            <item name="practice_sharks_listing_data_source" xsi:type="string">Practice\Sharks\Model\ResourceModel\Shark\Grid\Collection</item>
        </argument>
    </arguments>
</type>

Ui Component

<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">practice_sharks_listing.practice_sharks_listing_data_source</item>
        <item name="deps" xsi:type="string">practice_sharks_listing.practice_sharks_listing_data_source</item>
    </item>
    <item name="spinner" xsi:type="string">spinner_columns</item>
    <item name="buttons" xsi:type="array">
        <item name="add" xsi:type="array">
            <item name="name" xsi:type="string">add</item>
            <item name="label" xsi:type="string" translate="true">Add New Shark</item>
            <item name="class" xsi:type="string">primary</item>
            <item name="url" xsi:type="string">*/*/new</item>
        </item>
    </item>
</argument>
<dataSource name="practice_sharks_listing_data_source">
    <argument name="dataProvider" xsi:type="configurableObject">
        <argument name="class" xsi:type="string">Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider</argument>
        <argument name="name" xsi:type="string">practice_sharks_listing_data_source</argument>
        <argument name="primaryFieldName" xsi:type="string">shark_id</argument>
        <argument name="requestFieldName" xsi:type="string">id</argument>
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="component" xsi:type="string">Magento_Ui/js/grid/provider</item>
                <item name="update_url" xsi:type="url" path="mui/index/render"/>
                <item name="storageConfig" xsi:type="array">
                    <item name="indexField" xsi:type="string">shark_id</item>
                </item>
            </item>
        </argument>
    </argument>
</dataSource>
<columns name="spinner_columns">
    <selectionsColumn name="ids">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="resizeEnabled" xsi:type="boolean">false</item>
                <item name="resizeDefaultWidth" xsi:type="string">55</item>
                <item name="indexField" xsi:type="string">shark_id</item>
            </item>
        </argument>
    </selectionsColumn>
    <column name="shark_id">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="filter" xsi:type="string">textRange</item>
                <item name="sorting" xsi:type="string">asc</item>
                <item name="label" xsi:type="string" translate="true">ID</item>
            </item>
        </argument>
    </column>
    <column name="name">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="filter" xsi:type="string">text</item>
                <item name="editor" xsi:type="array">
                    <item name="editorType" xsi:type="string">text</item>
                    <item name="validation" xsi:type="array">
                        <item name="required-entry" xsi:type="boolean">true</item>
                    </item>
                </item>
                <item name="label" xsi:type="string" translate="true">Name</item>
            </item>
        </argument>
    </column>
</columns>

What am I missing? Something in the Collection, Ui_Component? I'm at a loss here.

1

Fix 1: In app/code/Practice/Sharks/view/adminhtml/ui_component/sharks_shark_listing.xml

Replace practice_sharks_listing to sharks_shark_listing

Fix 2: In app/code/Practice/Sharks/etc/di.xml, change data source to sharks_shark_listing_data_source

Fix 3: app/code/Practice/Sharks/Model/ResourceModel/Shark/Collection.php


<?php
namespace Practice\Sharks\Model\ResourceModel\Shark;

/**

 */
class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
{
    /**
     * @var string
     */
    protected $_idFieldName = 'shark_id';

    /**
     *
     */
    protected function _construct()
    {
        $this->_init('Practice\Sharks\Model\Shark', 'Practice\Sharks\Model\ResourceModel\Shark');
    }
}

2
  • 1
    You are a lifesaver, it would have taken me forever to spot that issue in the XML.
    – Erik B
    Feb 16 '19 at 8:52
  • What was the xml issue? Oct 12 '20 at 16:33
0

Just adding this here for others, also refer to Magento 2 : Custom grid keeps spinning and grid doesn't load if it's still not working.

0

Further explanation regarding marked answer (re: XML)

The marked answer shows things without explaining anything, and although the answer is an exact solution for the question posted, once you come here as someone looking for information, like me you might still not have any clear indication of what might be wrong.

TLDR: Some extra explanation needed for the accepted answer, check your XML.

  • Chances are like OP everything you did looks correct, but still not working, and almost always XML related for most things in Magento 2.

  • Check your data source, and make sure it matches inside di.xml and your_ui_component_file.xml , your data source that you define inside di.xml should be used within the ui components you need it.

  • More likely: You named your provider something different, but Magento 2 can't use it if it doesn't match your_ui_component_file.xml file name. Your provider elements in your UI component should be exactly named the same as your ui_component_vendor_module_grid_listing.xml file.

XML code

  • Assume that you named your ui component file ui_component_vendor_module_grid_listing.xml:
    <argument name="data" xsi:type="array">
        <item name="js_config" xsi:type="array">
            <item name="provider" xsi:type="string">ui_component_vendor_module_grid_listing.some_feature_listing_data_source</item>
        </item>
    </argument>
    <settings>
        <spinner>vendor_module_some_feature_columns</spinner>
        <deps>
            <dep>ui_component_vendor_module_grid_listing.some_feature_listing_data_source</dep>
        </deps>
                <!-- truncated -->

    <columns name="vendor_module_some_feature_columns">
        <settings>
            <editorConfig>
                <param name="selectProvider" xsi:type="string">ui_component_vendor_module_grid_listing.ui_component_vendor_module_grid_listing.vendor_module_some_feature_columns.ids</param>
                <!-- truncated -->
            <childDefaults>
                <param name="fieldAction" xsi:type="array">
                    <item name="provider" xsi:type="string">ui_component_vendor_module_grid_listing.ui_component_vendor_module_grid_listing.vendor_module_some_feature_columns_editor</item>
                <!-- truncated -->                  
  • Your di.xml file:
    • Add the entry into the \CollectionFactory node:
    <type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
        <arguments>
            <argument name="collections" xsi:type="array">
                <item name="some_feature_listing_data_source" xsi:type="string">Vendor\Module\Model\ResourceModel\Something\Grid\Collection</item>
            </argument>
        </arguments>
    </type>

Further Explanation

It seems that even though the data source (some_feature_listing_data_source) in this example, is not resolved by dependency injection by name only, but by ui_component_name.data_source_name only, so the way Magento 2 uses it inside the ui component feels extremely cumbersome, and 'ignores' a randomly named this_is_a_unique_grid_listing_data_source.some_feature_listing_data_source even though it feels like 'why is it there if it can't be used'.

Instead, the current implementation feels 'unused' and 'useless'.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.