0

I am using the extension amasty/single-step-checkout. They are using this mixin...

vendor\amasty\module-single-step-checkout\view\frontend\web\js\view\shipping-mixin.js (A)

...to extend this magento core javascript:

vendor\magento\module-checkout\view\frontend\web\js\view\shipping.js (B)

I try to extend the mixin (A) to add a few extra methods, otherwise I would have to override their whole script.

So I created the requirejs-config.js file to add my mixin.

app\code\Company\Shipping\view\frontend\requirejs-config.js:

var config = {

    map: {
        '*': {
            // I am overriding this file with my own, because I needed to replace a line to override a template with app\code\Company\Shipping\view\frontend\web\template\onepage\shipping\methods.html
            'Amasty_Checkout/js/model/one-step-layout':'Company_Shipping/js/model/one-step-layout'
        }
    },

    config: {
        mixins: {
            'Amasty_Checkout/js/view/shipping-mixin': {
                'Company_Shipping/js/view/shipping-mixin-ext': true
            }

      //    I also tried to extend the original script
      //    'Magento_Checkout/js/view/shipping': {
      //        'Company_Shipping/js/view/shipping-mixin-ext': true
      //    }
        }
    }
};

app\code\Company\Shipping\view\frontend\web\js\view\shipping-mixin-ext.js:

Attempt 1:

define([],
    function () {

    return function (Shipping) {
        return Shipping.extend({

            initialize: function () {
                this._super();
            },

            expressMethodActive: function () {
                ...
            },

            test: function() {
                ...
            },
        });
    };
});

Attempt 2:

define([],
    function () {

    var mixin = {

        expressMethodActive: function () {
            ...
        },

        test: function() {
            ...
        },
    };

    return function (target) {
        return target.extend(mixin);
    };
});

Then I call the new methods in the template.

app\code\Company\Shipping\view\frontend\web\template\onepage\shipping\methods.html:

<li id="opc-shipping_method"
    class="checkout-shipping-method"
    data-bind="fadeVisible: visible(), blockLoader: isLoading"
    role="presentation">
    <div class="checkout-shipping-method">
        <p class="step-title amcheckout-title"
           data-amcheckout-js="step-title"
           data-bind="i18n: getNameShippingMethod()"
           data-role="title"></p>
        <div class="step-content amcheckout-content"
             data-amcheckout-js="step-content"
             data-bind="mageInit: {'checkoutCollapsibleSteps': {}}">
            <div class="amcheckout-wrapper">
                <!-- ko fastForEach: getRegion('before-shipping-method-form') -->
                    <!-- ko template: getTemplate() --><!-- /ko -->
                <!-- /ko -->
                <div id="checkout-step-shipping_method">
                    <!-- ko if: rates().length  -->
                        <form class="form methods-shipping" id="co-shipping-method-form" data-bind="submit: setShippingInformation" novalidate="novalidate">
                            <div id="checkout-shipping-method-load">
                                <table class="table-checkout-shipping-method amcheckout-shipping-methods">
                                    <thead class="amcheckout-header">
                                    <tr class="row">
                                        <th class="col col-method" data-bind="i18n: 'Select Method'"></th>
                                        <th class="col col-price" data-bind="i18n: 'Price'"></th>
                                        <th class="col col-method" data-bind="i18n: 'Method Title'"></th>
                                        <th class="col col-carrier" data-bind="i18n: 'Carrier Title'" colspan="2"></th>
                                    </tr>
                                    </thead>
                                    <tbody class="amcheckout-items">

                                    <!--ko foreach: { data: rates(), as: 'method'}-->
                                        <tr class="row amcheckout-method"
                                            data-bind="
                                                click: $parent.selectShippingMethod,
                                                css : { '-selected' : $parent.isSelected() == (method.carrier_code + '_' + method.method_code) }">
                                                
                                            ...

                                            <td>
                                                Test
                                                <pre data-bind="text: $parent.expressMethodActive(method)"></pre>
                                            </td>
                                            
                                        ...

But no attempt works. If I go to the checkout then I get

Message: $parent.expressMethodActive is not defined

3
  • 1
    I have ran into this same issue before, it seems that creating a mixin of a mixin doesn't really work as the 'primary' mixin always overrides your 'secondary' mixin making it pointless. I didn't actually try this but I now think that using a shim may work as you can control the order of dependencies - requirejs.org/docs/api.html#config-shim and stackoverflow.com/questions/15471088/… – Ben Crook Oct 14 '20 at 9:01
  • Thx for the info. Hmm, not sure how to configure the shim. I think the only way is to override the core code of the Amasty Extension... but I guess update attempts with composer update will fail then... – Black Oct 14 '20 at 10:34
  • 1
    You can override the module's JS directly in the theme without using Composer – Ben Crook Oct 14 '20 at 10:40
0

I think Ben Crook is right. It is not possible. So I have to override the whole script with my own.

I created a new module Amasty_CheckoutOverrides and moved all my override templates and javascript files to it. Then I have overridden the files with this requirejs-config.js:

app\code\Amasty\CheckoutOverrides\view\frontend\requirejs-config.js

var config = {
    map: {
        '*': {
            'Amasty_Checkout/js/model/one-step-layout':'Amasty_CheckoutOverrides/js/model/one-step-layout',
            'Amasty_Checkout/js/view/shipping-mixin' : 'Amasty_CheckoutOverrides/js/view/shipping-mixin'
        }
    }
};

Important: If you update the original module for example with composer update then you have to check for changes in your overriden files and apply them manually if needed. For example if they patch a security hole, then you have to apply the patch yourself by looking at changes in the files and modify your files accordingly. Thats why I created a new module named Amasty_CheckoutOverrides so that I know on first sight which files I have overriden so I know which files I have to check when I update the module.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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