Skip to content

Magento 2 – how to add methods to a javascript file by using mixins?

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

vendoramastymodule-single-step-checkoutviewfrontendwebjsviewshipping-mixin.js (A)

…to extend this magento core javascript:

vendormagentomodule-checkoutviewfrontendwebjsviewshipping.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.

appcodeCompanyShippingviewfrontendrequirejs-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 appcodeCompanyShippingviewfrontendwebtemplateonepageshippingmethods.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
      //    }
        }
    }
};

appcodeCompanyShippingviewfrontendwebjsviewshipping-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.

appcodeCompanyShippingviewfrontendwebtemplateonepageshippingmethods.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