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.