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

Your Answer

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

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