Magento – Recoverable Error: Argument 1 passed to Magento\Framework\Data\Form::__construct() must be an instance of Magento\Framework\Data\Form\Element\Factory

blocksmagento2moduletemplate

I am developing a custom module for Magento 2.

Right now I have an error. When I run the Place Order in checkout page,
it is supposed to redirect me to a page where it says "You will be redirected to somewhere" for 5 seconds, and then redirect to the "somewhere".

But, I am getting this error in var/report

Recoverable Error: Argument 1 passed to Magento\Framework\Data\Form::__construct() must be an instance of Magento\Framework\Data\Form\Element\Factory, none given, called in C:\Apache24\htdocs\mag\app\code\Asiapay\Pdcptb\Block\Redirect.php on line 34 and defined in C:\Apache24\htdocs\mag\vendor\magento\framework\Data\Form.php on line 59

I have no idea why it shows this. Is there anything that I missed? I've tried to delete the var/generation content, so I'm sure it is not the that problem.

Block file (app\code\Asiapay\Pdcptb\Block\Redirect.php):

<?php

namespace Asiapay\Pdcptb\Block;

use Asiapay\Pdcptb\Model\PdcptbFactory;
use Magento\Customer\Model\Session;
use Magento\Framework\Data\Form;
use Magento\Framework\Data\Form\Element\Factory;
use Magento\Framework\View\Element\AbstractBlock;
use Magento\Framework\View\Element\Template\Context;

//use Magento\Framework\View\Element\Context;

class Redirect extends AbstractBlock
{
    /**
     * @var PdcptbFactory
     */
    protected $_modelPdcptbFactory;

    public function __construct(
        Context $context,
        PdcptbFactory $modelPdcptbFactory,
        array $data = []
    ) {
        $this->_modelPdcptbFactory = $modelPdcptbFactory;

        parent::__construct($context, $data);
    }

    protected function _toHtml()
    {
        $pdcptb = $this->_modelPdcptbFactory->create();

        $form = new Form();
        $form->setAction($pdcptb->getUrl())
            ->setId('pdcptb_checkout')
            ->setName('pdcptb_checkout')
            ->setMethod('post')
            ->setUseContainer(true);
        foreach ($pdcptb->getCheckoutFormFields() as $field => $value) {
            $form->addField($field, 'hidden', ['name' => $field, 'value' => $value]);
        }
        $html = '<html><body>';
        $html .= __('You will be redirected to the payment gateway in a few     seconds.');
        $html .= $form->toHtml();
        $html .= '<script type="text/javascript">require(["jquery", "prototype"], function(jQuery) {document.getElementById("pdcptb_checkout").submit();})</script>';

        $html .= '</body></html>';

        return $html;

    }
}

Controller file (app\code\Asiapay\Pdcptb\Controller\Pdcptb\Redirect.php):

<?php

namespace Asiapay\Pdcptb\Controller\Pdcptb;

use Magento\Framework\App\Action\Context;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Controller\Result\Raw\Interceptor;
use Magento\Framework\Controller\Result\RawFactory;
use Magento\Framework\Data\Form\Element\Factory;
use Magento\Framework\View\LayoutFactory;
use Magento\Framework\View\LayoutInterface;

class Redirect extends AbstractPdcptb
{
    /**
     * @var RawFactory
     */
    protected $_resultRawFactory;

    /**
     * @var LayoutFactory
     */
    protected $_viewLayoutFactory;

    public function __construct(
        Context $context,
        RawFactory $resultRawFactory,
        LayoutFactory $viewLayoutFactory
    ) {
        $this->_resultRawFactory = $resultRawFactory;
        $this->_viewLayoutFactory = $viewLayoutFactory;

        parent::__construct($context);
    }

    /**
     * When a customer chooses Pdcptb on Checkout/Payment page
     */
    public function execute()
    {

        /*      METHOD 1        */

        $session = ObjectManager::getInstance()->get('Magento\Checkout\Model\Session');
        $session->setPdcptbQuoteId($session->getQuoteId());
        $this->_resultRawFactory->create()->setContents($this->_viewLayoutFactory->create()->createBlock('Asiapay\Pdcptb\Block\Redirect')->toHtml());
        $session->unsQuoteId();
    }
}

Template file (app\code\Asiapay\Pdcptb\view\frontend\templates\form.phtml):

<fieldset class="form-list">
    <?php $_code = $this->getMethodCode() ?>
    <ul id="payment_form_<?php echo $_code ?>" style="display:none">
        <li>
            <?php echo __('You will be redirected to a secure payment page.') ?>
        </li>
    </ul>
</fieldset>

Best Answer

You can't instantiate an object of form without passing argument. Please refer file Magento\Framework\Data\Form.php wherein construct function there are four arguments (one is an array) so you must pass three arguments during initiate object of Form:

 class Form extends \Magento\Framework\Data\Form\AbstractForm
 {
     public function __construct(
         Factory $factoryElement,
         ElementCollectionFactory $factoryCollection,
         FormKey $formKey,
         $data = []
     ) {
         parent::__construct($factoryElement, $factoryCollection, $data);
         $this->_allElements = $this->_factoryCollection-create(['container' => $this]);
         $this->formKey = $formKey;
     }
 }

Your argument is not matching with construct function.