9

I've built an admin grid following a few tutorials and hit this error:

Warning: Invalid argument supplied for foreach() in /home/sadmin/mage/lib/internal/Magento/Framework/View/Element/UiComponent/DataProvider/DataProvider.php on line 253

I went to the file and saw this function:

protected function searchResultToOutput(SearchResultInterface $searchResult)
{
    $arrItems = [];

    $arrItems['items'] = [];
    foreach ($searchResult->getItems() as $item) {
        $itemData = [];
        foreach ($item->getCustomAttributes() as $attribute) {
            $itemData[$attribute->getAttributeCode()] = $attribute->getValue();
        }
        $arrItems['items'][] = $itemData;
    }

    $arrItems['totalRecords'] = $searchResult->getTotalCount();

    return $arrItems;
}

for my data, there are no custom attributes, so how do I bypass this part of the function for my grid to load? Var_dumping my $searchResult->getItems() shows my table data so I'm not sure why this is needed, any help or explanations are much appreciated :)

Thanks!

5
  • 4
    I got the same issue in one of my custom modules and found out that my [Vendor]\[Module]\Model\ResourceModel\[Module]\Grid\Collection::__constructor had called its' parent below this line $this->_init($model, $resourceModel); Then I moved the parent::__constructor to the top and issue got fixed. 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\Store
    – rukrlf
    Commented Oct 31, 2018 at 12:40
  • Did you find an answer?
    – Daniel
    Commented Sep 17, 2019 at 11:46
  • @Daniel unfortunately not from what I remember, think I went for a completely different approach entirely - though unfortunately, that project was closed so the code is not there :/ if someone has it on their machines I might be able to get the answer out and post, but that's a big if I'm afraid :/
    – treyBake
    Commented Sep 17, 2019 at 11:54
  • For me it was an issue with the declaration of the <virtualType> in di.xml. So I guess when a wrong dataProvider is passed to the UiComponent it leads to this error. $searchResult->getItems() the items where actual model instances instead of DataProvider/Model instances. I don't think that's enough for an answer but I hope this comment helps.
    – Daniel
    Commented Sep 17, 2019 at 13:16
  • 1
    @Daniel oo add it as answer if it's a good one^ might help some future visitor :)
    – treyBake
    Commented Sep 17, 2019 at 13:17

4 Answers 4

2

In my case the error occurred due to an wrong declaration of the <virtualType> in the di.xml.

The <virtualType> for the dataProvider can be declared the following:

<virtualType name="[Vendor]\[Module]\Model\ResourceModel\[Model]\Grid\Collection"
             type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
    <arguments>
        <argument name="mainTable" xsi:type="string">main_table</argument>
        <argument name="resourceModel" xsi:type="string">[Vendor]\[Module]\Model\ResourceModel\[Model]</argument>
    </arguments>
</virtualType>

On the name attribute of the <virtualType> I provided the wrong path to the Collection. Fixing the path did solve the problem with the error and the grid is displayed.

Due to the wrong declaration, the $searchResult->getItems() returned an array of [Vendor]/[Module]/Model/[Model] instead of an array containing Magento\Framework\View\Element\UiComponent\DataProvider\[Model] instances.

2

In my case, I needed to pass the object Magento\Framework\View\Element\UiComponent\DataProvider\Document to the custom collection class.

//di.xml file

    <type name="YourVendor\Example\Model\ResourceModel\ExampleTable\Grid\Collection">
        <arguments>
            <argument name="mainTable" xsi:type="string">example_post</argument>
            <argument name="eventPrefix" xsi:type="string">blog_post_grid_collection</argument>
            <argument name="eventObject" xsi:type="string">blog_post_object_grid_collection</argument>
            <argument name="resourceModel" xsi:type="string">YourVendor\Example\Model\ResourceModel\ExampleResource</argument>
            <argument name="model" xsi:type="string">Magento\Framework\View\Element\UiComponent\DataProvider\Document</argument>
        </arguments>
    </type>

The object Document converts the data in the format as shown in the image. This data is returned by the method $item->getCustomAttributes()

enter image description here

0

Normally, when creating a collection by extending \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection, we add something like this to our collection class:

    protected function _construct()
    {
        $this->_init(\Vendor\Module\Model\DiscountGroup::class, \Vendor\Module\Model\ResourceModel\DiscountGroup::class);
    }

But if we extend \Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult instead of AbstractCollection, then adding that code is a mistake, because it overrides $this->_init($this->document, $resourceModel); from \Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult::__construct.

Removing the override for the _construct method fixed the issue for me.

0

I was getting the same error in my custom grid and this was my constructor.

\Vendor\Module\Model\ResourceModel\View\Grid\Collection

public function __construct(
        LoggerInterface        $logger,
        Session                $session,
        ManagerInterface       $eventManager,
        StoreManagerInterface  $storeManager,
        EntityFactoryInterface $entityFactory,
        FetchStrategyInterface $fetchStrategy,
        $mainTable,
        $resourceModel,
        $model = 'Magento\Framework\View\Element\UiComponent\DataProvider\Document',
        AdapterInterface       $connection = null,
        AbstractDb             $resource = null
    )
    {
        $this->_init($model, $resourceModel);
        $this->setMainTable($mainTable);
        parent::__construct($logger, $session, $eventManager, $storeManager, $entityFactory, $fetchStrategy, $connection, $resource);
    }

after changing the argument a little bit like this it worked.

public function __construct(
        LoggerInterface        $logger,
        Session                $session,
        ManagerInterface       $eventManager,
        StoreManagerInterface  $storeManager,
        EntityFactoryInterface $entityFactory,
        FetchStrategyInterface $fetchStrategy,
        $mainTable,
        $eventPrefix,
        $eventObject,
        $resourceModel,
        $model = 'Magento\Framework\View\Element\UiComponent\DataProvider\Document',
        AdapterInterface       $connection = null,
        AbstractDb             $resource = null
    ){
        parent::__construct($logger, $session, $eventManager, $storeManager, $entityFactory, $fetchStrategy, $connection, $resource);
        $this->_eventPrefix = $eventPrefix;
        $this->_eventObject = $eventObject;
        $this->_init($model, $resourceModel);
        $this->setMainTable($mainTable);
    }

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