Magento 2.2 UI Component – Collection Not Loading in Admin Grid

collection;gridmagento2magento2.2uicomponent

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.

Best Answer

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');
    }
}