Magento 2 – How to Extend Core Block Constructor

dependency-injectionmagento2magento2.2

Let's say I have a helper class (let's call it \Vendor\Module\Helper\Cart) which I'd like to use in a block. I understand I should add the helper class in block constructor, so I should extend core block class

For instance vendor/magento/module-multishipping/Block/Checkout/Addresses.php

This is the constructor of that block class

public function __construct(
    \Magento\Framework\View\Element\Template\Context $context,
    \Magento\Framework\Filter\DataObject\GridFactory $filterGridFactory,
    \Magento\Multishipping\Model\Checkout\Type\Multishipping $multishipping,
    \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository,
    AddressConfig $addressConfig,
    \Magento\Customer\Model\Address\Mapper $addressMapper,
    array $data = []
) {
    $this->_filterGridFactory = $filterGridFactory;
    $this->_multishipping = $multishipping;
    $this->customerRepository = $customerRepository;
    $this->_addressConfig = $addressConfig;
    parent::__construct($context, $data);
    $this->addressMapper = $addressMapper;
    $this->_isScopePrivate = true;
}

I have tried this…

protected $cartHelper;

public function __construct(
    \Magento\Framework\View\Element\Template\Context $context,
    \Magento\Framework\Filter\DataObject\GridFactory $filterGridFactory,
    \Magento\Multishipping\Model\Checkout\Type\Multishipping $multishipping,
    \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository,
    AddressConfig $addressConfig,
    \Magento\Customer\Model\Address\Mapper $addressMapper,
    \Vendor\Module\Helper\Cart $cartHelper,
    array $data = []
) {
    $this->_filterGridFactory = $filterGridFactory;
    $this->_multishipping = $multishipping;
    $this->customerRepository = $customerRepository;
    $this->_addressConfig = $addressConfig;
    parent::__construct($context, $data);
    $this->addressMapper = $addressMapper;
    $this->_isScopePrivate = true;
    $this->cartHelper = $cartHelper;
}

But this throws error when compiling

Incompatible argument type: Required type: \Magento\Framework\Filter\DataObject\GridFactory. Actual type: array;

So, I have tried changing constructor in extended class for this

protected $cartHelper;

public function __construct(
    \Magento\Framework\View\Element\Template\Context $context,
    \Vendor\Module\Helper\Cart $cartHelper,
    array $data = []
) {
    parent::__construct($context, $data);
    $this->cartHelper = $cartHelper;
}

With no success… so I ended with the last try, which made setup:di:compile pass fine

protected $cartHelper;

public function __construct(
    \Magento\Framework\View\Element\Template\Context $context,
    \Magento\Framework\Filter\DataObject\GridFactory $filterGridFactory,
    \Magento\Multishipping\Model\Checkout\Type\Multishipping $multishipping,
    \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository,
    AddressConfig $addressConfig,
    \Magento\Customer\Model\Address\Mapper $addressMapper,
    \Vendor\Module\Helper\Cart $cartHelper,
    array $data = []
) {
    $this->_filterGridFactory = $filterGridFactory;
    $this->_multishipping = $multishipping;
    $this->customerRepository = $customerRepository;
    $this->_addressConfig = $addressConfig;
    \Magento\Sales\Block\Items\AbstractItems::__construct($context, $data);
    $this->addressMapper = $addressMapper;
    $this->_isScopePrivate = true;
    $this->cartHelper = $cartHelper;
}

So, question would be, is this the right approach to do this?

Best Answer

The problem is you're extending \Magento\Multishipping\Block\Checkout\Addresses but are passing the wrong parameters to the parent:__construct(...).

You should pass all the parameters the parent class requires. You need to pass this all of these classes to the parent construct.

\Magento\Framework\View\Element\Template\Context $context,
\Magento\Framework\Filter\DataObject\GridFactory $filterGridFactory,
\Magento\Multishipping\Model\Checkout\Type\Multishipping $multishipping,
\Magento\Customer\Api\CustomerRepositoryInterface $customerRepository,
\Magento\Customer\Model\Address\Config $addressConfig,
\Magento\Customer\Model\Address\Mapper $addressMapper,
array $data = []
Related Topic