Applying mixins to the minicart.js

Keeping in mind what has been done before, lets now do it right.

You will notice that editing the number of items to display is within this section of code

        return Component.extend({});

In fact, how things are set, maxItemsToDisplay is a property of this component.

On a contrary, this code

https://gist.github.com/marjan7790/9b8096668cb4a31e9a47ef1b5e733159

is not part of the Component object, but is well within the main anonymous function. This may not seem like an important thing, but actually, the way it is set leads to one important consequence:

This code is plain old jquery and not being part of the component means, that it sits there, loaded in the browser and listens for any direct clicks/taps.

This in particular means, it both gets executed as much as times there is a click/tap on the proper HTML element and has NO correlation/dependency on any other java script object that is already loaded. It just does a simple work on its own.

To confirm this, place a break-point in the original minicart.js and see how the execution is paused in the debugger every time you click to open the Mini cart.

Clear any earlier breakpoints and now place a break-point on this line

var self = this,

which is right within

https://gist.github.com/marjan7790/5cd955f5c20c8c51844c4d9f048195b9

and you will see that no matter what you do or click, the initialize function gets executed once and on page load.

Now keep this in mind, while we try to change the behavior of the Mini Cart component by applying mixins to it. (I’m assuming you already have created and enabled a module of yours, which is out of scope of this article.)

We will go through these two steps:

First, in you extension’s folder view/frontend add file requirejs-config.js with this content

https://gist.github.com/marjan7790/941eb1805171159d700fa2583358dcf0

And second, create the file minicart.js under the view/frontend/web/js folder of your extension, with this content

https://gist.github.com/marjan7790/49bbca41222c12f5f69d9e10169bb9ea

Re-deploy static content if you must, clear cache and voila, you are done!

What happened?

In requirejs-config.js, as the file name itself suggests, we have added configuration to requirejs, telling it to do something like:

RequireJs, there is a module under this path ‘Magento_Checkout/js/view/minicart’.
Would you please, find my new file under this path YourVendor_YourModule/js/minicart and apply mixins to it?

Mixins? Suffice it to say, there are two JS objects and you want to merge their properties and functions. Well, the idea behind is multiple inheritance and JS certainly makes this possible.
At the end of the operation, when mixins are applied, new object emerges that has the combined properties of both of the objects. This is not something that you can achieve with plain old Object Oriented Programming.
I have said this in a oversimplified manner, and some of you may want to continue elsewhere to gather more details about how mixins work.

OK, that given, our code, that it is supposed to be merged with the original minicart.js is

https://gist.github.com/marjan7790/69ca73c54b8754f9e2c36c00defec7e4

See, Magento has implemented RequireJs in a way that you are kindly getting a reference to the target object. I have named that object origMiniCart.

We might want to thank Underscore.js for the possibility to call origMiniCart.extend({}), but it is clear that with this we can properly override the component properties in a good way.

I have set maxItemsToDisplay: 3 and returned the extended component.


The code so far was solving requirement B: display only 3 items.

You will notice that the code that addresses requirement A  has nothing to with the component and it is mere jquery

https://gist.github.com/marjan7790/7dd23978ef049b1f91459d5add8cf786

Please notice that

https://gist.github.com/marjan7790/3f5b8a16fc17aea51b4b25267b1003b3

does NOT contain the initSidebar() call. The call to initSidebar() stays as is in the original minicart.js

Now, lets debug:

add a break-point at localBody.css(‘overflow’,’hidden’); in your minicart.js and one at initSidebar() in the original minicart.js

Click to show the Mini Cart.

You will notice that first the debugger stops in the overridden file , executing to hide the overflow, and only then moves to execute the initSidebar() in the original.

Now, lets clear any breakpoints for clarity and add new ones.
One at return origMiniCart.extend({ in your minicart.js and one at var self = this, within the initialize() method in the original minicart.js

When you reload the page, you will notice the same order of execution: first your code is executed, and then the execution moves to the original initialize().

For those that you have come this far, one last info.

Open file

https://gist.github.com/marjan7790/572c2cebff58aeda7caace08a90fb4c5

Locate this code

https://gist.github.com/marjan7790/88828f3ed71c55a0b2c01935974c579f

The comment above the function is sufficient enough to figure that the value to be modified, i.e. the original component is referred to as the “target”. After the modification the “target” will be returned.

Feel free to check the git repository for tag 0.1.0: https://github.com/marjan7790/minicart

Thank you for coming this far.

In the next article we will talk about parameters passing. Since this maxItemsToDisplay: 3 is a bit … hardcoded, no? 🙂

Leave a comment