I have a custom resource model mapping to a table named soldiers_thewatcher_watch with a primary key: watch_id. I added the Grid UI component as well as a controller and admin link, but when I access the view (/admin/thewatcher/grid/index/) the page is basically blank in admin (the admin page loads but there is no content within the content area). I've added 1 row of data directly in the database. I likely have a typo somewhere, but have been looking through everything for hours and cannot find where the problem is. A lot of code to follow, sorry, any help is greatly appreciated. **Route:** app/code/Soldiers/Thewatcher/etc/adminhtml/routes.xml ```xml <?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd"> <router id="admin"> <route id="theatcher" frontName="thewatcher"> <module name="Soldiers_Thewatcher"/> </route> </router> </config> ``` **Controller:** Soldiers/Thewatcher/Controller/Adminhtml/Grid/Index.php ```php namespace Soldiers\Thewatcher\Controller\Adminhtml\Grid; class Index extends \Magento\Backend\App\Action { /** * @var \Magento\Framework\View\Result\PageFactory */ protected $resultPageFactory; /** * Constructor * * @param \Magento\Backend\App\Action\Context $context * @param \Magento\Framework\View\Result\PageFactory $resultPageFactory */ public function __construct( \Magento\Backend\App\Action\Context $context, \Magento\Framework\View\Result\PageFactory $resultPageFactory ) { parent::__construct($context); $this->resultPageFactory = $resultPageFactory; } /** * Load the page defined in view/adminhtml/layout/exampleadminnewpage_helloworld_index.xml * * @return \Magento\Framework\View\Result\Page */ public function execute() { return $resultPage = $this->resultPageFactory->create(); } } ``` **Layout:** Soldiers/Thewatcher/view/adminhtml/layout/soldiers_thewatcher_grid_index.xml ```xml <?xml version="1.0"?> <page> <body> <referenceContainer name="content"> <uiComponent name="soldiers_thewatcher_watch_grid"/> </referenceContainer> </body> </page> ``` **Data Provider:** Soldiers/Thewatcher/Ui/Component/Listing/DataProviders/Soldiers/Thewatcher/Watch/Grid.php ```php <?php namespace Soldiers\Thewatcher\Ui\Component\Listing\DataProviders\Soldiers\Thewatcher\Watch; /** * Class Grid */ class Grid extends \Magento\Ui\DataProvider\AbstractDataProvider { public function __construct( $name, $primaryFieldName, $requestFieldName, \Soldiers\Thewatcher\Model\ResourceModel\Watch\CollectionFactory $collectionFactory, array $meta = [], array $data = [] ) { parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data); $this->collection = $collectionFactory->create(); } } ``` **Action Bar:** Soldiers/Thewatcher/Ui/Component/Listing/Column/Soldiersthewatcherwatchgrid/PageActions.php ```php <?php namespace Soldiers\Thewatcher\Ui\Component\Listing\Column\Soldiersthewatcherwatchgrid; /** * Class PageActions */ class PageActions extends \Magento\Ui\Component\Listing\Columns\Column { public function prepareDataSource(array $dataSource) { if (isset($dataSource["data"]["items"])) { foreach ($dataSource["data"]["items"] as & $item) { $name = $this->getData("name"); $id = "X"; if(isset($item["watch_id"])) { $id = $item["watch_id"]; } $item[$name]["view"] = [ "href"=>$this->getContext()->getUrl( "soldiers_thewatcher_watch_grid/watch/edit",["watch_id"=>$id]), "label"=>__("Edit") ]; } } return $dataSource; } } ``` **Grid:** Soldiers/Thewatcher/view/adminhtml/ui_component/soldiers_thewatcher_watch_grid.xml ```xml <?xml version="1.0"?> <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">soldiers_thewatcher_watch_grid.soldiers_thewatcher_watch_grid_data_source</item> <item name="deps" xsi:type="string">soldiers_thewatcher_watch_grid.soldiers_thewatcher_watch_grid_data_source</item> </item> <item name="spinner" xsi:type="string">soldiers_thewatcher_watch_grid_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">Add New</item> <item name="class" xsi:type="string">primary</item> <item name="url" xsi:type="string">*/Watch/new</item> </item> </item> </argument> <dataSource name="soldiers_thewatcher_watch_grid_data_source"> <argument name="dataProvider" xsi:type="configurableObject"> <argument name="class" xsi:type="string">Soldiers\Thewatcher\Ui\Component\Listing\DataProviders\Soldiers\Thewatcher\Watch\Grid</argument> <argument name="name" xsi:type="string">soldiers_thewatcher_watch_grid_data_source</argument> <argument name="primaryFieldName" xsi:type="string">watch_id</argument> <argument name="requestFieldName" xsi:type="string">id</argument> <argument name="data" xsi:type="array"> <item name="config" xsi:type="array"> <item name="update_url" xsi:type="url" path="mui/index/render"/> <item name="storageConfig" xsi:type="array"> <item name="indexField" xsi:type="string">watch_id</item> </item> </item> </argument> </argument> <argument name="data" xsi:type="array"> <item name="js_config" xsi:type="array"> <item name="component" xsi:type="string">Magento_Ui/js/grid/provider</item> </item> </argument> </dataSource> <listingToolbar name="listing_top"> <settings> <sticky>true</sticky> </settings> <paging name="listing_paging"/> <filters name="listing_filters"/> </listingToolbar> <columns name="soldiers_thewatcher_watch_grid_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">watch_id</item> <item name="sortOrder" xsi:type="number">10</item> </item> </argument> </selectionsColumn> <column name="watch_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> <actionsColumn name="actions" class="Soldiers\Thewatcher\Ui\Component\Listing\Column\Soldiersthewatcherwatchgrid\PageActions"> <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">107</item> <item name="indexField" xsi:type="string">watch_id</item> <item name="sortOrder" xsi:type="number">200</item> </item> </argument> </actionsColumn> </columns> </listing> ``` **Resource Model (Collection)** Soldiers/Thewatcher/Model/ResourceModel/Watch/Collection.php ```php <?php namespace Soldiers\Thewatcher\Model\ResourceModel\Watch; /** * Class Collection */ class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection { protected function _construct() { $this->_init('Soldiers\Thewatcher\Model\Watch','Soldiers\Thewatcher\Model\ResourceModel\Watch'); } } ``` **Resource Model (Entity)** Soldiers/Thewatcher/Model/ResourceModel/Watch.php ```php <?php namespace Soldiers\Thewatcher\Model\ResourceModel; /** * Class Watch */ class Watch extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb { protected function _construct() { $this->_init('soldiers_thewatcher_watch','watch_id'); } } ``` **Model** app/code/Soldiers/Thewatcher/Model/Watch.php ```php <?php namespace Soldiers\Thewatcher\Model; /** * Class Watch */ class Watch extends \Magento\Framework\Model\AbstractModel implements \Soldiers\Thewatcher\Api\Data\WatchInterface, \Magento\Framework\DataObject\IdentityInterface { const CACHE_TAG = 'soldiers_thewatcher_watch'; protected function _construct() { $this->_init('Soldiers\Thewatcher\Model\ResourceModel\Watch'); } public function getIdentities() { return [self::CACHE_TAG . '_' . $this->getId()]; } } ```