[SalesForce] Lightning Web Component (LWC) Class Definition Syntax

Lightning Web Components (LWC) are made up of multiple files in a bundle. For this question I am focusing on the component's main .js file where the web component js class is implemented.

Example code:

import { LightningElement, api } from 'lwc';
import { NavigationMixin } from 'lightning/navigation';
import doSomething from '@salesforce/apex/MyApexClass.doSomething';

export default class MyLWC extends NavigationMixin(LightningElement) {
    @api a;
    @api b;

    download() {
        let that = this;
        doSomething({
            param1: this.a,
            param2: this.b
        })
        .then((result) => {
            that.navigateToWebPage(result);
        })
        .catch((error) =>{
            console.log(`Error occured ${error}`);
        });
    }

    navigateToWebPage(url) {
        // Navigate to a URL
        this[NavigationMixin.Navigate]({
            type: 'standard__webPage',
            attributes: {
                url: url
            }
        },
        false // Replaces the current page in your browser history with the URL
      );
    }
}

There are two things I don't understand here:

  • extends NavigationMixin(LightningElement) syntax – why brackets? Can js classes extend more than one parent class?
  • this[NavigationMixin.Navigate] – judging by the code it seems like 'this' got assigned the Navigate function (and potentially other functions from NavigateMixin?) to its prototype. Why aren't we using NavigationMixin like any other imported component – just calling their functions directly, not through this?

Can someone explain what is actually happening when using this kind of class extensions/inheritance, and if the syntax used here is something standard from the web components world or something specific for LWC?

Thanks for your answers!

Best Answer

The navigation API uses JavaScript Mixins!

Mixin – is a generic object-oriented programming term: a class that contains methods for other classes. Some other languages allow multiple inheritance. JavaScript does not support multiple inheritance, but mixins can be implemented by copying methods into prototype.

Read more about mixins here and more about class based mixins here

I have always questioned on this since on how hard the syntax is and why lwc team have chosen mixin only for navigation. It seems to deviate away from composition and in this case inheritance is chosen over composition!

Response from LWC platform Team — LNS(Lightning Navigation Service) has it on their roadmap to move away from the Mixin because of the inconsistent look/feel.

The root quality of the navigation API that led to something different is that it’s a contextual API that should be handled like an event would, but we choose to surface it more like a traditional JS/function API to avoid the dependency on events and for possible future static analyzability that one could not get with events.

There is a roadmap to bring in alignment with single imports than creating a mixin class

Related Topic