I'm extending shipping method
section in checkout
page, and it's showing well.
But it's throwing error while clicking next button after filling shipping address
and shipping method
information in checkout
page.
Error: Fatal Error: 'Call to a member function getCommentCode() on
null'
for this I have written below code:
Learning/ABlock/etc/di.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Checkout\Model\ShippingInformationManagement">
<plugin name="save-in-quote" type="Learning\ABlock\Model\Checkout\ShippingInformationManagementPlugin" sortOrder="10"/>
</type>
</config>
Learning/ABlock/etc/events.xml
<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="sales_model_service_quote_submit_before">
<observer name="Learning_ABlock" instance="Learning\ABlock\Model\Observer\SaveAccountNoObserver"/>
</event>
</config>
Learning/ABlock/etc/extension_attributes.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
<extension_attributes for="Magento\Checkout\Api\Data\ShippingInformationInterface">
<attribute code="account_no" type="string"/>
</extension_attributes>
</config>
Learning/ABlock/Model/Checkout/ShippingInformationManagementPlugin.php
<?php
namespace Learning\ABlock\Model\Checkout;
class ShippingInformationManagementPlugin
{
protected $quoteRepository;
public function __construct(
\Magento\Quote\Model\QuoteRepository $quoteRepository
) {
$this->quoteRepository = $quoteRepository;
}
/**
* @param \Magento\Checkout\Model\ShippingInformationManagement $subject
* @param $cartId
* @param \Magento\Checkout\Api\Data\ShippingInformationInterface $addressInformation
*/
public function beforeSaveAddressInformation(
\Magento\Checkout\Model\ShippingInformationManagement $subject,
$cartId,
\Magento\Checkout\Api\Data\ShippingInformationInterface $addressInformation
) {
$extAttributes = $addressInformation->getExtensionAttributes();
$AccountNo = $extAttributes->getAccountNo();
$quote = $this->quoteRepository->getActive($cartId);
$quote->setAccountNo($AccountNo);
}
}
Learning/ABlock/Model/Observer/SaveAccountNoObserver.php
<?php
namespace VLCSolutions\ABlock\Model\Observer;
use Magento\Framework\Event\Observer as EventObserver;
use Magento\Framework\Event\ObserverInterface;
class SaveAccountNoObserver implements ObserverInterface
{
/**
* @var \Magento\Framework\ObjectManagerInterface
*/
protected $_objectManager;
/**
* @param \Magento\Framework\ObjectManagerInterface $objectmanager
*/
public function __construct(\Magento\Framework\ObjectManagerInterface $objectmanager)
{
$this->_objectManager = $objectmanager;
}
public function execute(EventObserver $observer)
{
$order = $observer->getOrder();
$quoteRepository = $this->_objectManager->create('Magento\Quote\Model\QuoteRepository');
/** @var \Magento\Quote\Model\Quote $quote */
$quote = $quoteRepository->get($order->getQuoteId());
$order->setAccountNo( $quote->getAccountNo() );
return $this;
}
}
Learning/ABlock/view/frontend/layout/checkout_index_index.xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="checkout.root">
<arguments>
<argument name="jsLayout" xsi:type="array">
<item name="components" xsi:type="array">
<item name="checkout" xsi:type="array">
<item name="children" xsi:type="array">
<item name="steps" xsi:type="array">
<item name="children" xsi:type="array">
<item name="shipping-step" xsi:type="array">
<item name="children" xsi:type="array">
<item name="shippingAddress" xsi:type="array">
<item name="children" xsi:type="array">
<item name="shippingAdditional" xsi:type="array">
<item name="component" xsi:type="string">uiComponent</item>
<item name="displayArea" xsi:type="string">shippingAdditional</item>
<item name="children" xsi:type="array">
<item name="additional_block" xsi:type="array">
<item name="component" xsi:type="string">Learning_ABlock/js/view/checkout/shipping/additional-block</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</argument>
</arguments>
</referenceBlock>
</body>
</page>
Learning/ABlock/view/web/js/view/checkout/shipping/additional-block.js
define([
'uiComponent'
], function (Component) {
'use strict';
return Component.extend({
defaults: {
template: 'Learning_ABlock/checkout/shipping/additional-block'
}
});
});
Learning/ABlock/view/web/template/checkout/shipping/additional-block.html
<div xmlns="http://www.w3.org/1999/html">
<div class="field">
<label class="label" for="account_no">
<span data-bind="i18n: 'Enter Account Number'"></span>
</label>
<div class="control">
<input class="input-text" id="account_no" name="account-no" type="text" ></input>
</div>
</div>
</div>
see below image showing my custom field
when I debugging $addressInformation->getExtensionAttributes();
is returning null.
Could you please suggest me where I went wrong?
Best Answer
So you need to pass value through js, in this case you need to overwrite following js Magento/Checkout/view/frontend/web/js/model/shipping-save-processor/default.js
So you go with following way:
Create Learning/ABlock/view/frontend/requirejs-config.js
Create Learning/ABlock/view/frontend/web/js/model/shipping-save-processor/default.js
Actually you need to pass input value by extension_attributes
One more things, modify your Learning/ABlock/view/web/template/checkout/shipping/additional-block.html
You can see here as an example.