In lightning, we have developed multiple components for different functionalities. All custom components include a lot of boilerplate code and we will have to exclude most of the redundant code by building generic function in the helper part of aura bundle. However, it wouldn’t be the perfect solution to avoid the redundancy as we will have to do the same for other components as well. For example, Communication between an apex controller and a component is written separately for each custom component, even if the components are related to each other. Are there any mechanisms available in lightning for abstracting the boilerplate into one component for others to make use of it?
From my experience, this can be solved by Inheritance as it makes the code more structured and flexible. The Salesforce Apex framework supports inheritance similar to what we see in object-oriented programming languages like Java and others. Is Aura framework built to support inheritance?
Yes, Lightning supports extending components based on hierarchy. However, it is not similar to the traditional one. In lightning, everything is treated as a component and it is a bundle of Helper, Controller, CSS, Render and Design. Super component is the extendable component which has extensible =’true’ or abstract = ‘true’ attributes in the header. The subcomponent would have the following attribute in the header.
When a super component extends a subcomponent, it inherits all of the attributes and the helper method of the parent. The abstracted components can’t be used directly in the markup since it’s only partially implemented.
Consider the following example.
BaseComponent.cmp, ChildComponent.cmp & TestApp.app
The BaseComponent displays its record attributes and the v.body section. The v.body section shows the markup of the sub-component. The extends attribute sets the c: BaseCompoent to indicate that the ChildComponent is a subcomponent of the c: BaseCompoent. The c: indicates the namespace of the super component which is the default namespace of lightning since it is unmanaged. A managed package should include the custom namespace defined in the Org.
The available attributes in the parent component are available in the child component to set and use. Here, the record attribute of the parent component is accessible in the child component to set the value using aura: set. You may have noticed that v.body is not defined in the parent and the child component as an attribute. The body attribute is inherited from the root component of aura and flows down to its decedent components. Normal attributes (like the record attribute in the BaseComponent ) are having the same value throughout the hierarchy but body attribute behaves differently in each level. Here, the body attribute holds the markup data of the child component.
The c: ChildComponent included in the TestApp shows the following output.
TestApp --- Output In parent Component - Record: Record Value Set From Child Component - Child Component
You can see that the Child Component text in the child component markup is set to the body attribute of the parent component.
TestApp --- Output
The above example shows how an abstracted component behaves in a lightning application when it is declared directly. The abstracted component can be used only for extending to other components.
The redundancy issue can be solved easily by employing an abstracted or extensible component. With this, we can have the attributes and helper methods of parent component shared among all its child components. A child component can implement any number of parent interfaces but can’t extend more than a single parent component. The best practice is to modularize all the complex logic ( like server interactions ) into abstract components which then can be extended to other components.