2

I'm at the end of my chain. I've tried rewriting the UI Component, I've played with the DataProvider, etc, etc and I just can't find any combination in which this works.

I've written previous grids that show items, but this one just refuses to.

For example:

Most curiously here is the "records found" text. Not "0 records found", but just a number-less complete lack.

There are no errors in my logs or my JavaScript console - just a complete lack of items in my grid.

<?xml version="1.0" encoding="utf-8"?>
<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">organization_listing.data_source</item>
            <item name="deps" xsi:type="string">organization_listing.data_source</item>
        </item>
        <item name="spinner" xsi:type="string">organization_listing_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 Organization</item>
                <item name="class" xsi:type="string">primary</item>
                <item name="url" xsi:type="string">*/*/new</item>
            </item>
        </item>
    </argument>
    <dataSource name="data_source">
        <argument name="dataProvider" xsi:type="configurableObject">
            <argument name="class" xsi:type="string">Briteskies\Organizations\Ui\DataProvider\Organizations\Grid\DataProvider</argument>
            <argument name="name" xsi:type="string">data_source</argument>
            <argument name="primaryFieldName" xsi:type="string">entity_id</argument>
            <argument name="requestFieldName" xsi:type="string">entity_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">entity_id</item>
                    </item>
                </item>
            </argument>
        </argument>
    </dataSource>
    <listingToolbar name="listing_top">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="sticky" xsi:type="boolean">true</item>
            </item>
        </argument>
        <bookmark name="bookmarks"/>
        <columnsControls name="columns_controls"/>
        <filters name="listing_filters">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="templates" xsi:type="array">
                        <item name="filters" xsi:type="array">
                            <item name="select" xsi:type="array">
                                <item name="component" xsi:type="string">Magento_Ui/js/form/element/ui-select</item>
                                <item name="template" xsi:type="string">ui/grid/filters/elements/ui-select</item>
                            </item>
                        </item>
                    </item>
                </item>
            </argument>
        </filters>
        <massaction name="listing_massaction">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="component" xsi:type="string">Magento_Ui/js/grid/tree-massactions</item>
                </item>
            </argument>
            <action name="edit">
                <argument name="data" xsi:type="array">
                    <item name="config" xsi:type="array">
                        <item name="type" xsi:type="string">edit</item>
                        <item name="label" xsi:type="string" translate="true">Edit</item>
                        <item name="callback" xsi:type="array">
                            <item name="provider" xsi:type="string">organization_listing.organization_listing.column_editor</item>
                            <item name="target" xsi:type="string">editSelected</item>
                        </item>
                    </item>
                </argument>
            </action>
            <action name="status">
                <argument name="data" xsi:type="array">
                    <item name="config" xsi:type="array">
                        <item name="type" xsi:type="string">status</item>
                        <item name="label" xsi:type="string" translate="true">Change status</item>
                    </item>
                </argument>
                <argument name="actions" xsi:type="array">
                    <item name="0" xsi:type="array">
                        <item name="type" xsi:type="string">enable</item>
                        <item name="label" xsi:type="string" translate="true">Enable</item>
                        <item name="url" xsi:type="url" path="organizations/index/massStatus">
                            <param name="status">1</param>
                        </item>
                    </item>
                    <item name="1" xsi:type="array">
                        <item name="type" xsi:type="string">disable</item>
                        <item name="label" xsi:type="string" translate="true">Disable</item>
                        <item name="url" xsi:type="url" path="organizations/index/massStatus">
                            <param name="status">2</param>
                        </item>
                    </item>
                </argument>
            </action>
        </massaction>
        <paging name="listing_paging"/>
    </listingToolbar>
    <columns name="organization_listing_columns">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="editorConfig" xsi:type="array">
                    <item name="selectProvider" xsi:type="string">organization_listing.organization_listing.organization_listing_columns.ids</item>
                    <item name="enabled" xsi:type="boolean">true</item>
                    <item name="indexField" xsi:type="string">id</item>
                    <item name="clientConfig" xsi:type="array">
                        <item name="saveUrl" xsi:type="url" path="charmoption/index/inlineEdit"/>
                        <item name="validateBeforeSave" xsi:type="boolean">false</item>
                    </item>
                </item>
                <item name="childDefaults" xsi:type="array">
                    <item name="fieldAction" xsi:type="array">
                        <item name="provider" xsi:type="string">organization_listing.organization_listing.column_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>
                    </item>
                </item>
            </item>
        </argument>
        <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">entity_id</item>
                    <item name="sortOrder" xsi:type="boolean">false</item>
                </item>
            </argument>
        </selectionsColumn>
        <column name="increment_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 name="sortOrder" xsi:type="number">100</item>
                    <item name="resizeEnabled" xsi:type="boolean">false</item>
                    <item name="resizeDefaultWidth" xsi:type="string">50</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="sorting" xsi:type="string">asc</item>
                    <item name="label" xsi:type="string" translate="true">Name</item>
                    <item name="sortOrder" xsi:type="number">200</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>
            </argument>
        </column>
        <column name="customer_group_id">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">text</item>
                    <item name="sorting" xsi:type="string">asc</item>
                    <item name="label" xsi:type="string" translate="true">Customer Group</item>
                    <item name="sortOrder" xsi:type="number">300</item>
                </item>
            </argument>
        </column>
        <column name="is_active">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">text</item>
                    <item name="label" xsi:type="string" translate="true">Status</item>
                    <item name="sortOrder" xsi:type="number">800</item>
                </item>
            </argument>
        </column>
    </columns>
</listing>

My first thought was, of course, there must be something wrong with the DataProvider. But it's pretty difficult to mess up a DataProvider.

<?php

// namespaces

class DataProvider extends AbstractDataProvider
{
    /** @var CollectionFactory */
    protected $collection;

    /** @var PoolInterface */
    protected $modifiers;

    public function __construct(
        $name,
        $primaryFieldName,
        $requestFieldName,
        CollectionFactory $organizationCollection,
        PoolInterface $modifierPool,
        array $meta = [],
        array $data = []
    ) {
        $this->modifiers = $modifierPool;
        parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data);
        $this->collection = $organizationCollection->create();
    }

    public function getMeta()
    {
        $meta = parent::getMeta();

        foreach ($this->modifiers->getModifiersInstances() as $modifier) {
            $meta = $modifier->modifyMeta($meta);
        }

        return $meta;
    }

    public function getData()
    {
        $data = parent::getData();

        foreach ($this->modifiers->getModifiersInstances() as $modifier) {
            $data = $modifier->modifyData($data);
        }

        return $data;
    }
}

Even removing the Pool modifier (getData() getMeta()) methods, we have the same result - so it can't be that - plus, I tested it as a command line function:

<?php

// namespaces

class Test extends Command
{
    protected $dp;

    public function __construct(DataProviderFactory $dp, $name = 'darley:test')
    {
        $this->dp = $dp->create([
            'name'             => 'test',
            'primaryFieldName' => 'entity_id',
            'requestFieldName' => 'entity_id',
            'data'             => [
                'config' => [
                    'component'     => 'Magento_Ui/js/grid/provider',
                    'update_url'    => 'mui/index/render',
                    'storageConfig' => [
                        'indexField' => 'entity_id',
                    ],
                ],
            ],
        ]);
        parent::__construct($name);
    }

    public function execute(InputInterface $input, OutputInterface $output)
    {
        $output->writeln('Count: '.$this->dp->count());
        var_dump($this->dp->getData());
    }
}

Which of course, works fine:

So I've just run out of ways to figure out why the Grid isn't loading in any data.

Why would a grid do this?

2 Answers 2

3

The key to the problem here is the output of the collection's ->toArray method. While it contains the entities desired, it does not contain them in the right format.

A typical flat table structure collection WILL output the expected array structure in Magento 2.1 - however, an EAV Collection will not.

In order to fix this grid, I had to add new keys to the top level of the resulting array.

    $data = [
        'totalRecords' => $this->getCollection()->getSize(),
        'items'        => array_values($this->getCollection()->toArray()),
    ];

With this structure, the grid rendered out as expected.

Please note that array_values may be necessary if the array is associative and your grid has select boxes.

2
  • Amazing worked perfectly for me! Thank you.
    – Dacod
    Feb 3, 2020 at 14:09
  • That saved my Hours of Debugging! Thanks alot.
    – Harish ST
    Feb 28, 2022 at 10:26
0

You can see module_cms as your example

In etc/di.xml

<type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
    <arguments>
        <argument name="collections" xsi:type="array">
            <item name="data_source" xsi:type="string">Namespace\YourModule\Model\ResourceModel\Organizations\Grid\Collection</item>
        </argument>
    </arguments>
</type>

Connect your data_source with your resourcemodel

<type name="Namespace\YourModule\Model\ResourceModel\Organizations\Grid\Collection">
    <arguments>
        <argument name="mainTable" xsi:type="string">db_table_name</argument>
        <argument name="eventPrefix" xsi:type="string">your_prefix_name</argument>
        <argument name="eventObject" xsi:type="string">your_event_name</argument>
        <argument name="resourceModel" xsi:type="string">Namespace\Module\Model\ResourceModel\Organizations</argument>
    </arguments>
</type>

Namespace\YourModule\Model\ResourceModel\Organizations\Grid\Collection
Main content will be

/**
 * @var AggregationInterface
 */
protected $aggregations;

/**
 * @param \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory
 * @param \Psr\Log\LoggerInterface $logger
 * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
 * @param \Magento\Framework\Event\ManagerInterface $eventManager
 * @param \Magento\Store\Model\StoreManagerInterface $storeManager
 * @param \Magento\Framework\EntityManager\MetadataPool $metadataPool
 * @param mixed|null $mainTable
 * @param \Magento\Framework\Model\ResourceModel\Db\AbstractDb $eventPrefix
 * @param mixed $eventObject
 * @param mixed $resourceModel
 * @param string $model
 * @param null $connection
 * @param \Magento\Framework\Model\ResourceModel\Db\AbstractDb|null $resource
 *
 * @SuppressWarnings(PHPMD.ExcessiveParameterList)
 */
public function __construct(
    \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory,
    \Psr\Log\LoggerInterface $logger,
    \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
    \Magento\Framework\Event\ManagerInterface $eventManager,
    \Magento\Store\Model\StoreManagerInterface $storeManager,
    \Magento\Framework\EntityManager\MetadataPool $metadataPool,
    $mainTable,
    $eventPrefix,
    $eventObject,
    $resourceModel,
    $model = 'Magento\Framework\View\Element\UiComponent\DataProvider\Document',
    $connection = null,
    \Magento\Framework\Model\ResourceModel\Db\AbstractDb $resource = null
) {
    parent::__construct(
        $entityFactory,
        $logger,
        $fetchStrategy,
        $eventManager,
        $storeManager,
        $metadataPool,
        $connection,
        $resource
    );
    $this->_eventPrefix = $eventPrefix;
    $this->_eventObject = $eventObject;
    $this->_init($model, $resourceModel);
    $this->setMainTable($mainTable);
}

/**
 * @return AggregationInterface
 */
public function getAggregations()
{
    return $this->aggregations;
}

/**
 * @param AggregationInterface $aggregations
 * @return $this
 */
public function setAggregations($aggregations)
{
    $this->aggregations = $aggregations;
}

/**
 * Get search criteria.
 *
 * @return \Magento\Framework\Api\SearchCriteriaInterface|null
 */
public function getSearchCriteria()
{
    return null;
}

/**
 * Set search criteria.
 *
 * @param \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria
 * @return $this
 * @SuppressWarnings(PHPMD.UnusedFormalParameter)
 */
public function setSearchCriteria(\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria = null)
{
    return $this;
}

/**
 * Get total count.
 *
 * @return int
 */
public function getTotalCount()
{
    return $this->getSize();
}

/**
 * Set total count.
 *
 * @param int $totalCount
 * @return $this
 * @SuppressWarnings(PHPMD.UnusedFormalParameter)
 */
public function setTotalCount($totalCount)
{
    return $this;
}

/**
 * Set items list.
 *
 * @param \Magento\Framework\Api\ExtensibleDataInterface[] $items
 * @return $this
 * @SuppressWarnings(PHPMD.UnusedFormalParameter)
 */
public function setItems(array $items = null)
{
    return $this;
}

Don't forget flush cache after change code

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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