14

There are 2 Shipping methods and by default no one is selected, user have to manually select one, as a result it say shipping (undefined-undefined). I want that First item should be automatically comes selected if none is selected how this can be done in magento 2

6 Answers 6

25

As i understood from your question is that you want to always have a shipping method selected when someone comes on checkout page.

To achieve this, we need to override a javascript from Magento_Checkout module.

First things first, we need to create a module :

Namespace/Module/registration.php

<?php

\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Namespace_Module',
    __DIR__
);

Namespace/Module/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Namespace_Module" setup_version="1.0.0">
        <sequence>
            <module name="Magento_Checkout"/>
        </sequence>
    </module>
</config>

After this, we need to create the requirejs for overriding that js.

Namespace/Module/view/frontend/requirejs-config.js

var config = {
    map: {
        '*': {
            'Magento_Checkout/js/model/checkout-data-resolver': 'Namespace_Module/js/model/checkout-data-resolver'
        }
    }
};

Now we have to copy checkout-data-resolver.js from Magento_Checkout/view/frontend/web/js/model in our module with the same path Namespace_Module/view/frontend/web/js/model

After that, we need to change a condition inside the function resolveShippingRates: function (ratesData)

From:

            ...

            if (ratesData.length == 1) {
                //set shipping rate if we have only one available shipping rate
                selectShippingMethodAction(ratesData[0]);

                return;
            }

            ...

To:

           ...

            if (ratesData.length >= 1) {
                //set shipping rate if we have only one available shipping rate
                selectShippingMethodAction(ratesData[0]);

                return;
            }

            ...

And thats it, all you have to do now is:

  • Activate the module : php bin/magento module:enable Namespace_Module
  • Run a setup upgrade : php bin/magento setup:upgrade
  • Do a static deploy : php bin/magento setup:static-content:deploy
5
  • If I want to provide option in configuration for which shipping method should be selected then what types of changes in need to do for that?
    – Indian
    Commented Jun 1, 2017 at 11:07
  • 2
    This is not working properly. It will not working when we fill the form and then when we try to select other shipping method then we are not able to select it. it will select default shipping method again automatically.
    – Indian
    Commented Jul 31, 2017 at 5:42
  • 1
    I modified this and added the call to selectShippingMethodAction(ratesData[0]); downn a bit lower in the method, after it looks for the already selected methods, so it doesn't override them.
    – thaddeusmt
    Commented Jan 9, 2018 at 22:04
  • it's working good. But when using onestepcheckout, how can we get the shipping amount to order summary updated as well? it seems the shipping cost in the order summary first get updated when manually clicking on the shipping method Commented Jun 19, 2019 at 12:56
  • This works great, but i would recommend using mixins, scroll a few answers down how to use those and then use the lines from this answer ;)
    – Sanne
    Commented Feb 11, 2020 at 11:42
9
if (ratesData.length >= 1) {
  //set shipping rate if we have only one available shipping rate
  selectShippingMethodAction(ratesData[0]);

  return;
}

This will make it impossible to select any other shipping option. This solves the issue for me:

if (ratesData.length == 1) {
    //set shipping rate if we have only one available shipping rate;
    selectShippingMethodAction(ratesData[0]);

    return;
}

if (ratesData.length >= 1) {
    //set shipping rate if we have only one available shipping rate
    if(!selectedShippingRate) {
        selectShippingMethodAction(ratesData[0]);
    }
}
3
  • In which file is this?
    – Erfan
    Commented Jan 23, 2018 at 4:15
  • @Benjamin, it's working good. But when using onestepcheckout, how can we get the order total updated as well? it seems the shipping cost in the order total is only updated when manually clicking on the shipping method. Commented Jun 19, 2019 at 11:39
  • 1
    This should be the accepted answer
    – Tailtiu
    Commented Nov 22, 2019 at 7:06
8

While the above methods suggest overriding the js functions, I would recommend using mixins to avoid unnecessary code clashes:

In your frontend requirejs-config.js add the following:

var config = {
    config: {
        mixins: {
            'Magento_Checkout/js/model/checkout-data-resolver': {
                '{Vendor}/{Module}/model/checkout-data-resolver': true
            }
        }
    }
};

In your checkout-data-resolver.js

define([
    'underscore',
    'mage/utils/wrapper',
    'Magento_Checkout/js/checkout-data',
    'Magento_Checkout/js/action/select-shipping-method',
    'Magento_Checkout/js/action/select-payment-method'
],function (_, wrapper, checkoutData, selectShippingMethodAction) {
    'use strict';

    return function (checkoutDataResolver) {

        var resolveShippingRates = wrapper.wrap(
            checkoutDataResolver.resolveShippingRates,
            function (originalResolveShippingRates, ratesData) {
                // select your shipping method here using the ratesData and selectShippingMethodAction
                return originalResolveShippingRates(ratesData);
            }
        );

        return _.extend(checkoutDataResolver, {
            resolveShippingRates: resolveShippingRates
        });
    };
});

Alternatively, you can download the module here which allows you to select a default shipping and payment method: Default Shipping & Payment Method [M2]

2
  • 1
    Absolutely brilliant solution using mixins. Scalpel rather than a sledgehammer. The best answer to this question by quite some way.
    – Dom
    Commented Nov 16, 2020 at 22:07
  • Nice Solution instead of Override checkout data resolver js file Commented Jul 29, 2022 at 5:13
5

There is no need for entire module to achieve this change. You can simple extend the Checkout module and override in in your theme.

  1. Copy the js file checkout-data-resolver.js
    from
    vendor\magento\module-checkout\view\frontend\web\js\model
    to
    app\design\frontend\Namespace\ThemeName\Magento_Checkout\web\js\model.

  2. Locate line with following code:
    if (ratesData.length == 1) {
    and replace it with:
    if (ratesData.length >= 1 && !selectedShippingRate) {

3
  • 1
    It does not retain the values if the customer has default shipping address pre-populated in the checkout page or the zip code is prepopulated in cart page.is there any way to retain the values in this case?
    – sahana
    Commented Mar 18, 2019 at 8:59
  • it's working good. But how can we get the shipping amount to order summary updated as well? it seems the shipping cost in the order summary is only updated when manually clicking on the shipping method Commented Jun 19, 2019 at 12:51
  • thanks working fine Commented Feb 20, 2020 at 12:38
3

What you probably want to do is select the cheapest shipping method by default.

In your module over ride checkout-data-resolver, optionally you might be able to use a mixin instead.

var config = {
    map: {
        '*': {
            'Magento_Checkout/js/model/checkout-data-resolver':'MyModule_Checkout/js/view/checkout-data-resolver'
        }
    }
}

in the resolveShippingRates method modify as below:

        /**
         * @param {Object} ratesData
         */
        resolveShippingRates: function (ratesData) {
            var selectedShippingRate = checkoutData.getSelectedShippingRate(),
                availableRate = false;
            //Added to find the cheapest rate
            var lowestRateId = _.min(_.keys(ratesData), function(k) { return ratesData[k].amount; });

            if (ratesData.length === 1) {
                //set shipping rate if we have only one available shipping rate
                selectShippingMethodAction(ratesData[0]);

                return;
            }

            // added to select the cheapest rate if no method selected

            if(lowestRateId && !selectedShippingRate && ratesData.length > 0) {
                selectShippingMethodAction(ratesData[lowestRateId]);
            }
4
  • it's working good. But how can we get the shipping amount to order summary updated as well? it seems the shipping cost in the order summary is only updated when manually clicking on the shipping method Commented Jun 19, 2019 at 12:52
  • @MagentoLearner have you got solution to this problem?
    – user00247
    Commented Jul 19, 2019 at 7:06
  • @user00247 not yet. if you have a solution please share. Commented Jul 19, 2019 at 11:07
  • @MagentoLearner I am also searching for a solution :(
    – user00247
    Commented Jul 19, 2019 at 12:52
0

Anyone who is using onestepcheckout can try this:

if (ratesData.length >= 1) {
  setTimeout(function(){
     selectShippingMethodAction(ratesData[0]);
  }, 500)
  return;
}

I know it's looking stupid, but for some reason adding that delay really worked for me. Shipping cost is updating itself like this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.