1

Trying to save record in admin grid with create API interface but getting fatal Error link below

Fatal error: Uncaught TypeError: Argument 1 passed to Mage2\Inquiry\Model\InquiryRepository::save() must be an instance of Mage2\Inquiry\Api\Data\InquiryInterface, instance of Mage2\Inquiry\Model\Inquiry given, called in /var/www/html/2-3/app/code/Mage2/Inquiry/Controller/Adminhtml/Inquiry/Save.php on line 89 and defined in /var/www/html/2-3/app/code/Mage2/Inquiry/Model/InquiryRepository.php:114

Code of file Save.php under controller

namespace Mage2\Inquiry\Controller\Adminhtml\Inquiry;

use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
use Magento\Backend\App\Action\Context;
use Mage2\Inquiry\Api\InquiryRepositoryInterface;
use Mage2\Inquiry\Model\Inquiry;
use Mage2\Inquiry\Model\InquiryFactory;
use Magento\Framework\App\Request\DataPersistorInterface;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Registry;


class Save extends \Mage2\Inquiry\Controller\Adminhtml\Inquiry implements HttpPostActionInterface
{

    /**
     * @var DataPersistorInterface
     */
    protected $dataPersistor;

    /**
     * @var InquiryFactory
     */
    private $inquiryFactory;

    /**
     * @var InquiryRepositoryInterface
     */
    private $inquiryRepository;

    /**
     * @param Context $context
     * @param Registry $coreRegistry
     * @param DataPersistorInterface $dataPersistor
     * @param InquiryFactory|null $inquiryFactory
     * @param InquiryRepositoryInterface|null $inquiryRepository
     */
    public function __construct(
        Context $context,
        Registry $coreRegistry,
        DataPersistorInterface $dataPersistor,
        InquiryFactory $inquiryFactory = null,
        InquiryRepositoryInterface $inquiryRepository = null
    ) {
        $this->dataPersistor = $dataPersistor;
        $this->inquiryFactory = $inquiryFactory
            ?: \Magento\Framework\App\ObjectManager::getInstance()->get(InquiryFactory::class);
        $this->inquiryRepository = $inquiryRepository
            ?: \Magento\Framework\App\ObjectManager::getInstance()->get(InquiryRepositoryInterface::class);
        parent::__construct($context, $coreRegistry);
    }

    /**
     * Save action
     *
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
     * @return \Magento\Framework\Controller\ResultInterface
     */
    public function execute()
    {
        /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
        $resultRedirect = $this->resultRedirectFactory->create();
        $data = $this->getRequest()->getPostValue();
        if ($data) {
            if (isset($data['status']) && $data['status'] === 'true') {
                $data['status'] = Inquiry::STATUS_ENABLED;
            }
            if (empty($data['inquiry_id'])) {
                $data['inquiry_id'] = null;
            }

            /** @var \Mage2\Inquiry\Model\Inquiry $model */
            $model = $this->inquiryFactory->create();

            $id = $this->getRequest()->getParam('inquiry_id');
            if ($id) {
                try {
                    $model = $this->inquiryRepository->getById($id);
                } catch (LocalizedException $e) {
                    $this->messageManager->addErrorMessage(__('This inquiry no longer exists.'));
                    return $resultRedirect->setPath('*/*/');
                }
            }

            $model->setData($data);

            try {
                $this->inquiryRepository->save($model);
                $this->messageManager->addSuccessMessage(__('You saved the inquiry.'));
                $this->dataPersistor->clear('mage2_inquiry');
                return $this->processInquiryReturn($model, $data, $resultRedirect);
            } catch (LocalizedException $e) {
                $this->messageManager->addErrorMessage($e->getMessage());
            } catch (\Exception $e) {
                $this->messageManager->addExceptionMessage($e, __('Something went wrong while saving the inquiry.'));
            }

            $this->dataPersistor->set('mage2_inquiry', $data);
            return $resultRedirect->setPath('*/*/edit', ['inquiry_id' => $id]);
        }
        return $resultRedirect->setPath('*/*/');
    }

    /**
     * Process and set the Inquiry return
     *
     * @param \Magento\Cms\Model\Inquiry $model
     * @param array $data
     * @param \Magento\Framework\Controller\ResultInterface $resultRedirect
     * @return \Magento\Framework\Controller\ResultInterface
     */

    private function processInquiryReturn($model, $data, $resultRedirect)
    {
        $redirect = $data['back'] ?? 'close';

        if ($redirect ==='continue') {
            $resultRedirect->setPath('*/*/edit', ['inquiry_id' => $model->getId()]);
        } else if ($redirect === 'close') {
            $resultRedirect->setPath('*/*/');
        } else if ($redirect === 'duplicate') {
            $duplicateModel = $this->inquiryFactory->create(['data' => $data]);
            $duplicateModel->setId(null);
            $duplicateModel->setStatus(Inquiry::STATUS_DISABLED);
            $this->inquiryRepository->save($duplicateModel);
            $id = $duplicateModel->getId();
            $this->messageManager->addSuccessMessage(__('You duplicated the inquiry.'));
            $this->dataPersistor->set('mage2_inquiry', $data);
            $resultRedirect->setPath('*/*/edit', ['inquiry_id' => $id]);
        }
        return $resultRedirect;
    }
}

InquiryInterface.php

namespace Mage2\Inquiry\Api\Data;

/**
 * Inquiry Interface
 * @api
 * @since 100.0.2
 */
interface InquiryInterface
{
    /**#@+
     * Constants for keys of data array. Identical to the name of the getter in snake case
     */
    const INQUIRY_ID      = 'inquiry_id';
    const NAME            = 'name';
    const MOBILE_NUMBER   = 'mobile_number';
    const MESSAGE         = 'message';
    const EMAIL           = 'email';
    const PRODUCT_ID      = 'product_id';
    const STATUS          = 'status';
    const DISPLAY_FRONT   = 'display_front';
    const ADMIN_MESSAGE   = 'admin_message';
    /**#@-*/

    /**
     * Get ID
     *
     * @return int|null
     */
    public function getId();

    /**
     * Get Name
     *
     * @return string
     */
    public function getName();

    /**
     * Get Mobile Number
     *
     * @return string|null
     */
    public function getMobileNumber();

    /**
     * Get message
     *
     * @return string|null
     */
    public function getMessage();

    /**
     * Get email
     *
     * @return string|null
     */
    public function getEmail();

    /**
     * Get Product Id
     *
     * @return string|null
     */
    public function getProductId();

    /**
     * Get Display in front setting
     *
     * @return string|null
     */
    public function getDisplayFront();

    /**
     * Get Admin message
     *
     * @return string|null
     */
    public function getAdminMessage();

    /**
     * Get status
     *
     * @return bool|null
     */
    public function getStatus();

    /**
     * Set ID
     *
     * @param int $id
     * @return InquiryInterface
     */
    public function setId($id);

    /**
     * Set Name
     *
     * @param string $name
     * @return InquiryInterface
     */
    public function setName($name);

    /**
     * Set MobileNumber
     *
     * @param string $mobile_number
     * @return InquiryInterface
     */
    public function setMobileNumber($mobile_number);

    /**
     * Set message
     *
     * @param string $message
     * @return InquiryInterface
     */
    public function setMessage($message);

    /**
     * Set Email
     *
     * @param string $email
     * @return InquiryInterface
     */
    public function setEmail($email);

    /**
     * set ProductId
     *
     * @param int $product_id
     * @return InquiryInterface
     */
    public function setProductId($product_id);

    /**
     * Set Display Front setting
     *
     * @param bool|int $display_front
     * @return InquiryInterface
     */
    public function setDisplayFront($display_front);

    /**
     * Set Admin Message
     *
     * @param string $admin_message
     * @return InquiryInterface
     */
    public function setAdminMessage($admin_message);

    /**
     * Set Status
     *
     * @param bool|int $status
     * @return InquiryInterface
     */
    public function setStatus($status);
}
1

In the etc/di.xml, you need to add preference for \Mage2\Inquiry\Api\Data\InquiryInterface. E.g:

<preference for="Mage2\Inquiry\Api\Data\InquiryInterface" type="Mage2\Inquiry\Model\Inquiry"/>

In Mage2\Inquiry\Model\Inquiry, you will need to implement that interface

class Inquiry implements \Mage2\Inquiry\Api\Data\InquiryInterface
{
    // content
}

After that, re-run the bin/magento setup:upgrade to clear all generated data and cache.

P/s: I also notice this in the __constructor()

$this->inquiryFactory = $inquiryFactory
            ?: \Magento\Framework\App\ObjectManager::getInstance()->get(InquiryFactory::class);
$this->inquiryRepository = $inquiryRepository
            ?: \Magento\Framework\App\ObjectManager::getInstance()->get(InquiryRepositoryInterface::class);

Is there any idea why ObjectManager used here? ObjectManager is the rival of DependencyInjection

Good luck!

  • In etc/di.xml defined, but let me check model – Yogesh Feb 26 at 5:22
  • I am follow Magento_Cms module, same thing defined in block/controller/adminhtml/block/save.php – Yogesh Feb 26 at 5:31
  • @Yogesh You don't need to follow everything defined in core, especially thing like ObjectManager. As Alant Kent quoted: "Do what we say, not what we do" :) – Toan Nguyen Feb 26 at 7:04
  • Yes this is for learning purpose tutorial so I am doing what they do. – Yogesh Feb 26 at 7:09

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.