As you pointed out, when you click "Ship here" a HTTP POST request is dispatched to "/V1/carts/mine/estimate-shipping-methods-by-address-id"
REST API (from module-quote).
If you take a look at module-quote/etc/webapi.xml
you will find the url:
<route url="/V1/carts/mine/estimate-shipping-methods-by-address-id" method="POST">
<service class="Magento\Quote\Api\ShippingMethodManagementInterface" method="estimateByAddressId"/>
<resources>
<resource ref="self" />
</resources>
<data>
<parameter name="cartId" force="true">%cart_id%</parameter>
</data>
</route>
You can notice that under the <route>
element there is <service>
element with the class="Magento\Quote\Api\GuestShipmentEstimationInterface"
and method="estimateByExtendedAddress"
. Now obviously, the estimateByAddressId
method cannot be instantiated from an interface.
Here comes in scene the magento 2 dependency injection. Look at module-quote/etc/di.xml
file that maps an interface(Magento\Quote\Api\ShippingMethodManagementInterface
) dependency to a preferred implementation class(Magento\Quote\Model\ShippingMethodManagement
).
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Magento\Quote\Api\ShippingMethodManagementInterface" type="Magento\Quote\Model\ShippingMethodManagement" />
...................
</config>
This is how estimateByAddressId
method is called.
Useful links:
Magento 2 Web APIs:
http://devdocs.magento.com/guides/v2.0/get-started/bk-get-started-api.html
http://devdocs.magento.com/guides/v2.0/extension-dev-guide/service-contracts/service-to-web-service.html
Magento 2 Dependency injection:
http://devdocs.magento.com/guides/v2.0/extension-dev-guide/depend-inj.html
http://magento-quickies.alanstorm.com/post/68129858943/magento-2-injecting-interfaces
Okay, I have figured out how to set the shipping method programmatically:
Firstly, all my dependencies:
define(
[
'ko',
'jquery',
'Magento_Ui/js/form/form',
'uiRegistry',
'Magento_Checkout/js/model/quote',
'Magento_Checkout/js/model/resource-url-manager',
'Magento_Checkout/js/action/create-shipping-address',
'Magento_Checkout/js/model/error-processor',
'Magento_Checkout/js/model/shipping-service',
'Magento_Checkout/js/model/cart/totals-processor/default',
'Magento_Checkout/js/model/shipping-rate-registry',
'Magento_Checkout/js/action/select-shipping-method',
'Magento_Checkout/js/checkout-data'
],
function (
ko,
$,
Component,
uiRegistry,
quote,
resourceUrlManager,
createShippingAddress,
errorProcessor,
shippingService,
totalsDefaultProvider,
rateRegistry,
selectShippingMethodAction,
checkoutData
) {
...
Then, the magic promise:
setShippingMethod: function (carrier, method, title) {
return new Promise((resolve, reject) => {
let data = {
carrier_code: carrier,
method_code: method,
carrier_title: title,
method_title: title
};
selectShippingMethodAction(data);
checkoutData.setSelectedShippingRate(code + '_' + method);
if (quote.shippingMethod()) {
resolve(quote.shippingMethod());
} else {
reject(quote.shippingMethod());
}
});
}
So then in your event (or whatever):
setShippingMethod(
methodData['carrier_code'], methodData['warehouse_id'], methodData['title']
).then(
(shippingMethod) => {
totalsDefaultProvider.estimateTotals(quote.shippingAddress());
}
).catch(
(err) => failHandlerMethod(err)
);
Optional, you can also add the shipping address:
let payload = JSON.stringify({
addressInformation: {
address: {
countryId: "country",
postcode: "postcode",
regionId: "region"
},
shipping_carrier_code: "carrier_code",
shipping_method_code: "method_code"
}
});
let addr = createShippingAddress(payload);
rateRegistry.set(address.getCacheKey(), addr);
Best Answer
getUrl()
function defined inYou can use this function just add file path in your define function.