Code Reuse in Salesforce’ Lightning

Part 1: Inheritance

Sameed H. Khan
5 min readOct 9, 2018

This (somewhat opinionated) series aims to explore a few patterns that promote reuse of code in Salesforce’ proprietary Lightning Component Framework and provide some practical examples along the way.

In part 1, we will cover inheritance just because it’s a tricky topic in the javascript community. There exists different schools of thought on whether inheritance is good or evil (the ever so frequently mentioned gorilla banana problem). The merits of the prototypal inheritance model used in Javascript vs. the class-based inheritance model used in traditional object oriented programming languages such as Java or C++ are often hotly debated, as can be demonstrated by searching for Inheritance on medium.

Class-based inheritance is reusing functionality by creating classes (which are blue-prints or templates for object creation) and extending them to inherit their behavior and in the process creating a subclass relationship.

Prototypal inheritance reuses functionality by reusing an existing object, by cloning and extending it, and is made possible by delegation (if a method is called that is not directly owned by an object, find a method that might be related to it by looking up the prototype chain)

A deep dive into inheritance is beyond the scope of this article; however, the key things to note are:

  1. for better or worse (I assure you, it is for the better), Javascript uses prototypal inheritance
  2. inheritance is nothing more a design pattern and a code reuse mechanism

I believe a lot of the confusion stems from the fact that prototypal inheritance is called inheritance and developers coming in from traditional OOP languages expect it to work like the inheritance model they are used to. It doesn’t do that, of course, since it is a fundamentally different method of reusing code and the name behaviour delegation is perhaps more apt. The “class” syntax in ES6 adds to this confusion since it is not really class-based inheritance under the hood, but merely syntactic sugar for one way of using prototypal inheritance. While a complete understanding of prototypal inheritance is not necessary for this article, I find it important to mention because inheritance in lightning emulates class-based inheritance but is implemented using prototypal inheritance (Since that is what Javascript supports). Hence, for developers coming into lightning from OOP languages, it is possible to encounter behaviour that is not explained by understanding class-based inheritance and that would be a good time to read up on Javascript fundamentals.

Ever since the Visualforce days, Salesforce has pushed for a component based architecture that has now become ubiquitous part of modern front end development. Lightning continues in that path and enables developers to enjoy the benefits that stem from adopting a component based architecture. These include better separation of concerns, improved maintainability, independent release and deployment cycles, and better code reuse. The issue however comes from the fact that Lightning is an opinionated framework and tries to fight Javascript’s functional programming nature (and also its dynamic type system). As a result, components in Lightning are not compositional like they are in React, and thus does not allow patterns like higher order components, which have become increasingly popular when it comes to reusing code in React.

Instead, Lightning provides the basic constructs of inheritance and encapsulation from object-oriented programming through emulating class-based inheritance, abstract classes, and interfaces. As for whether inheritance is good or bad, I take a neutral stance. There are other mechanisms for reuse that are superior (the platitude “favour composition over inheritance” comes to mind), but I do feel that inheritance is not the evil it is often made out to be; it is merely misused. A single level of inheritance - as is done in React when creating components to reuse functionality that is common across all components - can be useful and I advocate doing something similar in Lightning. Just don’t go overboard and create deep component inheritance hierarchies. There is almost never any use case for it.

The aura:component tag in Lightning supports the following four attributes, extensible, abstract, extends, and implements which are used to describe the inheritance behaviour of that component. Details of OOP behaviour and the rules for inheritance in Lightning can be found Salesforce’ official documentation. A simplified summary of the important points is as follows:

Each component can extend one extensible component and implement multiple interfaces.

Abstract components have partial implementation of functionality and can’t be used directly in markup. The sub component extending an abstract component must complete the implementation of functionality.

A subcomponent that extends a super component will inherit the attributes, events and the helper methods of the super component.

That’s enough theory for now. Let’s delve into some code. The mark up below creates an abstract extensible component that registers an application event and a component event. These are event templates that will be reused when firing any events from any sub component that extends our abstract component.

<aura:component 
abstract="true"
extensible="true"
>

<aura:registerEvent name="ComponentEvent" type="c:ComponentEvent"/>
<aura:registerEvent name="ApplicationEvent" type="c:ApplicationEvent"/>


{!v.body}
</aura:component>

The helper file implements the following functions which will be inherited by sub components.

Sub component’s extend the Abstract component by using the extends attribute in the aura:component tag.

<aura:component extends="AbsComponent"></aura:component>

The inherited methods can be called using the helper parameter that gets passed to every controller method in the Lightning component. For instance, the execute action method can be used as follows to call an aura enabled apex method on the server (in keeping the theme of practical examples in this blog, let’s say the apex method takes in a contact Id and returns the contact record) as follows.

It should be noted that the executeAction method on the abstract component uses Javascript’s Promise feature. More information on how to use Promises effectively in Lightning can be found here. This pattern for calling server actions through a helper method on the super component using Promises is useful in that it provides all the benefits of Promises(more composable, avoiding callback hell, inversion of control, and improved readability) while reducing the boilerplate code that is usually written for when calling apex methods from lightning.

In addition, the the pattern of registering event templates for Lightning’s component and application events on the abstract component helps avoid the boilerplate code that would otherwise be written for firing and handling events. Reusing the same Lightning event for all communication also reduces the number of files that you need to keep track of, since each event in Lightning needs the creation of its own resource folder. The following is the mark up for a template of a component event. The same applies for an application event .

<aura:event type="COMPONENT" description="Component Event template">
<aura:attribute access="public" name="type" type="String"/>
<aura:attribute access="public" name="payload" type="Object"/>
</aura:event>

The type attribute in the action is a String that enables the component that fires the action to provide a name to the action, and the component that handles the action to identify the action by it’s named type. The payload attribute of type Object enables components to communicate data of any format through events.

While writing this blog, I realised that there was more to cover on this topic than I had originally anticipated and have therefore decided to split it into at least three parts. In the next part we shall take a look at Interfaces in lightning.

--

--