Mixins - JavaScript | LWC. A short introduction

Mixins - JavaScript | LWC. A short introduction

One of the most used quotes regarding mixins is from Mixin-based Inheritance Gilad Bracha and William Cook.

A mixin is an abstract subclass; i.e. a subclass definition that may be applied to different superclasses to create a related family of modified classes.

We only need to think about the quote in the context of class extensibility in JavaScript. That a class can only be extended by one, another class. And we might be able to figure out what mixins are meant to achieve.

Basically, mixins allow us to do a kind of multiple inheritance. By using mixins, we can extend a class with an unlimited number of other classes because each mixin can extend another mixin. While preserving powerful JavaScript language features such as:

  • Working super() call in constructors
  • Accessing properties by using the super keyword
  • Working instanceof keyword


What about first-class functions? It's a feature of languages that classes and functions are treated like any other variable. A class can be passed to the function as an argument. Or it can be assigned to a declared variable. Is such a feature of the language useful? Of course it is and is essential in building mixins in JavaScript!


Now we know what mixins are and what they are for. Let's go through a practical example.

Let’s assume that we have built a simple LWC component. Wizard to add a new college application. Let's call it a Study Application Component.

Brak alternatywnego tekstu dla tego zdjęcia

After some time, someone assigned us a ticket saying that we need to add toast-related functionality to our component. We don't want to change our perfect code by adding functionality that is not strictly related to our component. Let's extend our component with the Toast features mixin. New functions will be in a different class and what's more important will be reusable.

But before that let’s see on the current inheritance of our LWC component. Our component is already extended by the LightningElement class.

Brak alternatywnego tekstu dla tego zdjęcia
Brak alternatywnego tekstu dla tego zdjęcia

It's a good time to use mixins because we need to extend our class with two other classes. Let's create a Toast mixin and include it in our component declaration.

import { ShowToastEvent } from "lightning/platformShowToastEvent"

let ToastService = (superclass) => class extends superclass {

    showToast(variant, message, title, mode = "dismissible") {
        dispatchEvent(new ShowToastEvent({
            variant,
            message,
            title,
            mode
        }));
    }

    showSuccessToast(message, title = "Success") {
        this.showToast("success", message, title);
    }

}

export { ToastService };        
Brak alternatywnego tekstu dla tego zdjęcia
Brak alternatywnego tekstu dla tego zdjęcia

We didn't add any new logic to our component. We just added new responsibilities and now, our component has the ability to display our success toast!

Brak alternatywnego tekstu dla tego zdjęcia

What about the syntax? We need to know which parts of the class will be inherited by the other class. Let's consider the syntax we have to use in the LWC and take another look at the last example.

Brak alternatywnego tekstu dla tego zdjęcia

In this case, the LightningElement class is extended with the TosatService class. This creates the application mixin. Next, the StudyApplicationComponent class is extended with the mentioned application mixin. So the superclass of the LightningElement is ToastService. The superclass of the StudyApplicationComponent is the application mixin.


Do you think the current syntax is confusing? I have a good message for you! You can make use of the first-class JavaScript language attribute to change the syntax to whatever you want. Below you can find two examples of how you can do it.

Brak alternatywnego tekstu dla tego zdjęcia
class MixinLoader {
  constructor(superclass) {
    this.superclass = superclass;
  }
  with(...mixins) {
    return mixins.reduce((accumulator, mixin) => mixin(accumulator), this.superclass);
  }
}

let mix = (superclass) => new MixinLoader(superclass);
export { mix };        

And the second one, in the builder style!

Brak alternatywnego tekstu dla tego zdjęcia
class MixinsBuilder {
  constructor(superclass) {
    this.superclass = superclass;
  }

  loadToastMixin() {
    this.superclass = ToastMixin(this.superclass);
    return this;
  }
  …
  build() {
    return this.superclass;
  }
}

let base = (superclass) => new MixinsBuilder(superclass);
export { base };        


Jakub Katny

Salesforce Technical Leader | CRM Manager | Salesforce Trailblazer Community Group Leader

1y

Nice! Waiting for more content 😉

Like
Reply
Adam Siwek

🔧 ForVendi: Customizable Salesforce Solutions for Every Client Need

1y

Daniel Legawiec really nice article, thanks for sharing!

Like
Reply

To view or add a comment, sign in

More articles by Daniel Legawiec

  • Spot the Smells: 7 Code Smells That Make Your Code Look Bad

    1. Data Clump 🏋️♂️ When variables stick together like inseparable buddies Ever find yourself passing the same group of…

  • Power of External IDs in Salesforce

    Organizations leveraging Salesforce for customer relationship management often struggle with the complexities of…

  • LWC Debugging

    During reading this article you will be working with the developer console of your browser. All the tools were tested…

    2 Comments
  • Light DOM - LWC

    Each component we create works in a particular mode. By default, it's Shadow DOM mode.

    4 Comments
  • Skinny Tables - Salesforce

    Skinny tables are one of the performance optimization methods that Salesforce offers us. In more detail, these are the…

    5 Comments
  • CRUD-sensitive LWC component

    In this article, I'll show you step-by-step how to create LWC components that respond to any CRUD change made to a…

  • Code Standardization Tools - Salesforce

    The problem of code consistency across many developers or development teams is very common. Imagine that a new…

    1 Comment
  • Standard LWC Decorators

    In this article, I'm going to remind you of some important knowledge about the standard LWC decorators. Because most…

  • OAuth 2.0 Flows. Authorization to the Salesforce

    Starting with the definition of OAuth 2.0.

Insights from the community

Others also viewed

Explore topics