0

I've got an issue using ui component on front in a large module. The model I'm using for my grid is used at several other points. But I discovered my configuration in di.xml is doing some strange things.

<virtualType name="VENDOR\MODULE\Model\ResourceModel\ModelName\Collection" type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
    <arguments>
        <argument name="mainTable" xsi:type="string">vendor_module_modelname</argument>
        <argument name="resourceModel" xsi:type="string">VENDOR\MODULE\Model\ResourceModel\ModelName</argument>
    </arguments>
</virtualType>

Then when I'm using the factory to create my collection, as following

public function __construct(
    \VENDOR\MODULE\Model\ModelName $modelFactory
)
{
    $this->modelFactory= $modelFactory;
}

 public function execute()
 {
    $this->modelFactory->create();

I've got the following error :

Type Error occurred when creating object:

In the logs I have more infos

 Type Error occurred when creating object: VENDOR\MODULE\Model\ModelName, Argument 4 passed to VENDOR\MODULE\Model\ModelName::__construct() must be an instance of VENDOR\MODULE\Model\ResourceModel\ModelName\Collection, instance of Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult given, called in /var/www/project/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php on line 117 [] []

When I delete the virtual type, my model can be used with no problem. But the UI component crash.

Do you have any idea how to resolve that problem ? I couldn't find any existing subject linked to this problem but if you find any... Let me know ! Thank you ;)

EDIT : There is the code of my model VENDOR/MODULE/Model/ModelName

<?php

namespace VENDOR\MODULE\Model;

use VENDOR\MODULE\Api\Data\ModelInterface;
use VENDOR\MODULE\Api\Data\ModelInterfaceFactory;
use Magento\Framework\Api\DataObjectHelper;

class ModelName extends \Magento\Framework\Model\AbstractModel
{

    protected $modelDataFactory;

    protected $dataObjectHelper;

    protected $_eventPrefix = 'vendor_mymodel_name';

    /**
     * @param \Magento\Framework\Model\Context $context
     * @param \Magento\Framework\Registry $registry
     * @param ModelInterfaceFactory $modelDataFactory
     * @param DataObjectHelper $dataObjectHelper
     * @param \VENDOR\MODULE\Model\ResourceModel\ModelName $resource
     * @param \VENDOR\MODULE\Model\ResourceModel\ModelName\Collection $resourceCollection
     * @param array $data
     */
    public function __construct(
        \Magento\Framework\Model\Context $context,
        \Magento\Framework\Registry $registry,
        \VENDOR\MODULE\Model\ResourceModel\ModelName $resource,
        \VENDOR\MODULE\Model\ResourceModel\ModelName\Collection $resourceCollection,
        \VENDOR\MODULE\Api\Data\ModelName InterfaceFactory $modelDataFactory,
        \Magento\Framework\Api\DataObjectHelper $dataObjectHelper,
        array $data = []
    ) {
        $this->modelDataFactory = $modelDataFactory;
        $this->dataObjectHelper = $dataObjectHelper;
        parent::__construct($context, $registry, $resource, $resourceCollection, $data);
    }

    /**
     * Retrieve model with data
     * @return ModelNameInterface
     */
    public function getDataModel()
    {
        $modelData = $this->getData();

        $modelDataObject = $this->modelDataFactory->create();
        $this->dataObjectHelper->populateWithArray(
            $modeDataObject,
            $modelData,
            ModelInterface::class
        );

        return $modelDataObject;
    }
}

EDIT 2 : I've tryed some more things, unsuccessfully for the moment. As I couldn't get the user Id in the model, for any reason, I tried to get it from a helper. No more success.

I finnally tried with a DataProvider (Ui/DataProvider/DataProvider.php), that I saw in negotiableQuote. No more Success...

<?php

namespace VENDOR\MODULE\Ui\DataProvider;

use Magento\Framework\Api\FilterBuilder;
use Magento\Framework\Api\Search\SearchCriteriaBuilder;
use Magento\Framework\View\Element\UiComponent\DataProvider\Reporting;
use Magento\Framework\Api\SearchResultsInterface;
/**
 * Class DataProvider
 * @package VENDOR\MODULE\Ui\DataProvider
 */
class DataProvider extends \Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider
{

    /**
     * @var \VENDOR\MODULE\Model\ModelNameRepository
     */
    private $ModelNameRepository;

    /**
     * @var \Magento\Authorization\Model\UserContextInterface
     */
    private $userContext;

    /**
     * @var \Magento\Store\Model\StoreManagerInterface
     */
    private $storeManager;

    /**
     * @var \Magento\Company\Model\Company\Structure
     */
    private $structure;

    /**
     * @var \Magento\Framework\App\RequestInterface
     */
    protected $request;

    /**
     * @var \Magento\Company\Api\AuthorizationInterface
     */
    private $authorization;

    /**
     * DataProvider constructor.
     * @param string $name
     * @param string $primaryFieldName
     * @param string $requestFieldName
     * @param Reporting $reporting
     * @param SearchCriteriaBuilder $searchCriteriaBuilder
     * @param \Magento\Framework\App\RequestInterface $request
     * @param FilterBuilder $filterBuilder
     * @param \VENDOR\MODULE\Model\ModelNameRepository $ModelNameRepository
     * @param \Magento\Authorization\Model\UserContextInterface $userContext
     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
     * @param \Magento\Company\Model\Company\Structure $structure
     * @param \Magento\Company\Api\AuthorizationInterface $authorization
     * @param array $meta
     * @param array $data
     */
    public function __construct(
        $name,
        $primaryFieldName,
        $requestFieldName,
        Reporting $reporting,
        SearchCriteriaBuilder $searchCriteriaBuilder,
        \Magento\Framework\App\RequestInterface $request,
        FilterBuilder $filterBuilder,
        \VENDOR\MODULE\Model\ModelNameRepository $ModelNameRepository,
        \Magento\Authorization\Model\UserContextInterface $userContext,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Company\Model\Company\Structure $structure,
        \Magento\Company\Api\AuthorizationInterface $authorization,
        array $meta = [],
        array $data = []
    ) {
        parent::__construct(
            $name,
            $primaryFieldName,
            $requestFieldName,
            $reporting,
            $searchCriteriaBuilder,
            $request,
            $filterBuilder,
            $meta,
            $data
        );
        $this->ModelNameRepository = $ModelNameRepository;
        $this->userContext = $userContext;
        $this->storeManager = $storeManager;
        $this->structure = $structure;
        $this->request = $request;
        $this->authorization = $authorization;
    }

    /**
     * {@inheritdoc}
     */
    public function getData()
    {
        return $this->formatOutput($this->getSearchResult());
    }

    /**
     * Returns Search result.
     *
     * @return SearchResultsInterface
     */
    public function getSearchResult()
    {
        $this->addOrder('entity_id', 'DESC');
        $customerId = $this->getCustomerId();
        var_dump($customerId);
        $filter = $this->filterBuilder
            ->setField('main_table.company_id')
            ->setConditionType('eq')
            ->setValue($customerId)
            ->create();
        $this->searchCriteriaBuilder->addFilter($filter);
        $this->searchCriteria = $this->searchCriteriaBuilder->create();
        $this->searchCriteria->setRequestName($this->name);

        return $this->ModelNameRepository->getList($this->getSearchCriteria(), true);
    }

    /**
     * @return int|null
     */
    private function getCustomerId()
    {
        return $this->userContext->getUserId() ?  : null;
    }

    /**
     * @param SearchResultsInterface $searchResult
     * @return array
     */
    private function formatOutput(SearchResultsInterface $searchResult)
    {
        $arrItems = [];
        $arrItems['totalRecords'] = $searchResult->getTotalCount();

        $arrItems['items'] = [];
        foreach ($searchResult->getItems() as $item) {
            $itemData = [];
            foreach ($item->getData() as $key => $value) {
                $itemData[$key] = $value;
            }
            $arrItems['items'][] = $itemData;
        }
        return $arrItems;
    }

and there is my new di.xml (I left the comments of the old try)

<virtualType name="Naval\MyOffers\Model\ResourceModel\Offers\Grid\Collection" type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
    <arguments>
        <argument name="mainTable" xsi:type="string">naval_myoffers_offers</argument>
        <argument name="resourceModel" xsi:type="string">Naval\MyOffers\Model\ResourceModel\Offers\Collection</argument>
    </arguments>
</virtualType>
<!--<type name="Naval\MyOffers\Model\ResourceModel\Offers\Grid\Collection">-->
    <!--<arguments>-->
        <!--<argument name="mainTable" xsi:type="string">naval_myoffers_offers</argument>-->
        <!--<argument name="resourceModel" xsi:type="string">Naval\MyOffers\Model\ResourceModel\Offers</argument>-->
    <!--</arguments>-->
<!--</type>-->
<type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
    <arguments>
        <argument name="collections" xsi:type="array">
            <item name="naval_myoffers_offers_listing_data_source" xsi:type="string">Naval\MyOffers\Model\ResourceModel\Offers\Grid\Collection</item>
        </argument>
    </arguments>
</type>

** EDIT 3 : The situation Changed yesterday. ** It's working again as I'm using the data provider (See Edit 2), but the customer session does not work anymore. I cannot get the customer Id to filter in my DataProvider.

  • I think you just need to run command "setup:di:compile". – Yogesh Sep 4 at 12:47
  • Thank you for the answer, but no, I already tried it several times, and once again just now. It has no effect on that "bug". – Mric Sep 4 at 13:02
  • Can you please provide code of your model (VENDOR\MODULE\Model\ModelName)? – Yogesh Sep 5 at 4:27
  • Post Edited, I added my model – Mric Sep 5 at 6:51
  • try deleting generated folder manually and rerun .. – aravind Sep 6 at 6:48
0

Try changing your di.xml as follows, i have added Grid before collection. But no need to create a Grid folder place the collection file as usual in

VENDOR/MODULE/Model/ResourceModel/ModelName/Collection

<virtualType name="VENDOR\MODULE\Model\ResourceModel\ModelName\Grid\Collection" type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
    <arguments>
        <argument name="mainTable" xsi:type="string">vendor_module_modelname</argument>
        <argument name="eventPrefix" xsi:type="string">vendor_module_grid_collection</argument>
        <argument name="eventObject" xsi:type="string">module_grid_collection</argument>
        <argument name="resourceModel" xsi:type="string">VENDOR\MODULE\Model\ResourceModel\ModelName</argument>
    </arguments>
</virtualType>

To get Customer id,

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$customerSession = $objectManager->get('Magento\Customer\Model\Session');
if($customerSession->isLoggedIn()) {
    $customerSession->getCustomer()->getId();
}
  • That is what I have already. I Initially created the Grid/Collection class and add a filter in the _beforeLoad method. But the /Magento\Customer\Model\Session->getCustomer->getId() returned null. Now I have the same VirtualType as you suggested me, with the data provider. (I filter in the dataProvider.) But still no successfull result. – Mric Sep 6 at 7:06
  • could you update the code with the changes.. – aravind Sep 6 at 7:09
  • I updated it and added the new di.xml, thank you for your return – Mric Sep 6 at 7:16
  • I have updated my answer.. – aravind Sep 6 at 7:16
  • Magento\Customer\Model\Session->getCustomer()->getId() is still returning null, even with the changes you proposed... – Mric Sep 6 at 7:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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