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.

6
  • I think you just need to run command "setup:di:compile". Commented Sep 4, 2019 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
    Commented Sep 4, 2019 at 13:02
  • Can you please provide code of your model (VENDOR\MODULE\Model\ModelName)? Commented Sep 5, 2019 at 4:27
  • Post Edited, I added my model
    – Mric
    Commented Sep 5, 2019 at 6:51
  • try deleting generated folder manually and rerun ..
    – aravind
    Commented Sep 6, 2019 at 6:48

1 Answer 1

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();
}
8
  • 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
    Commented Sep 6, 2019 at 7:06
  • could you update the code with the changes..
    – aravind
    Commented Sep 6, 2019 at 7:09
  • I updated it and added the new di.xml, thank you for your return
    – Mric
    Commented Sep 6, 2019 at 7:16
  • I have updated my answer..
    – aravind
    Commented Sep 6, 2019 at 7:16
  • Magento\Customer\Model\Session->getCustomer()->getId() is still returning null, even with the changes you proposed...
    – Mric
    Commented Sep 6, 2019 at 7:23

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.