More value with lightning value providers

More value
with lightning
value providers

Lightning Value Providers

Salesforce cloud platform offers the whole variety of customization options. Those include point-and-click tools like Lightning App Builder, Process Builder, Visual Flow and Workflow alongside development tools like Apex, Visualforce, Lightning Aura Components, Lightning Aura Events, Lightning Aura Tokens, Lightning Aura Standalone application and Lightning Web Components.

Lightning Aura Components development involves the development of a custom HTML and Javascript code using standard Lightning component library and custom syntax. Such a syntax is applied to access data or bind an action for a specific event handlings; whereas value providers being a part of this syntax, are used for custom component development in Lightning.

What are Lightning Value Providers? Value providers in Lightning make it possible to access data and the related actions. They encapsulate the related values together similar to how an object encapsulates properties and methods. Both standard and custom value providers share the same syntax. However, before diving deeper into custom value providers implementation, we need to make sure that we understand how standard value providers work and how they can be used for custom application development.

Standard component value providers

  1. View. Syntax: {!v.value} or cmp.get(“v.value”) in Javascript.
  2. Controller. Syntax: {!c.action}

Component-related value providers are the most common and widely known value providers. The standard value providers for a component are v (view) and c (controller). View value provider provides component’s attributes set. This value provider enables developers to access the value of a component’s attribute in the component’s markup. Controller value provider supplies component’s controller actions which enables developers to wire up event handlers and actions for the component.

There is one important thing I would like to highlight as it might not be widely known. Namely, there is a difference between two-way binding and one-way binding. In order to use two-way binding, the syntax {!v.value} should be used while for one-way binding, the syntax {#v.value} should be used. For the two-way binding, whenever the value is changed, it is automatically reflected on the UI, while for the one-way binding, only the initial value provided on component initialization will be reflected on the UI. The two-way binding syntax in Lightning is known as “Bound Expression” while one-way binding syntax is known as “Unbound Expression”.

Standard global value providers

There are six standard global value providers supplying global values and methods that a component can use in expressions.

  1. Global Id. Syntax: {!globalId} or cmp.getGlobalId() in Javascript.
  2. Browser. Syntax: {!$Browser.property} or $A.get(“$Browser.property”)
  3. Content Asset. Syntax:  “{!$ContentAsset.name + ‘pathinarchive=<path>’}”
  4. Label. Syntax: {!$Label.c.name} or $A.get(“$Label.c.name“)
  5. Locale. Syntax: {!$Locale.property} or $A.get(“$Locale.property”)
  6. Resource. Syntax: “{!$Resource.name + ‘/<path‘}”

The Global Id value provider supplies component global Id, which is a generated runtime-unique Id of the component instance. This id is not guaranteed to be the same beyond the lifetime of a component, so it’s not worth to be relied on. A global Id can be useful though, in order to differentiate between multiple instances of a component or for debugging purposes.

The Browser value provider helps to determine the operating system and the type of a device the browser is running on. Attribute formFactor return DESKTOP, PHONE or TABLET enum values which signify if a desktop client, a smartphone or a tablet client is used. Properties isAndroid and isIOS determine if the browser is running on an Android or iOS device. Properties isPhone and isTablet duplicate functionality of formFactor attribute indication if the browser is running on a smartphone, a tablet or on iPad. Attributes isIPad, isIPhone and isWindowsPhone provide more details about the device the browser is running on.

The Content Asset and Resource providers let a developer reference images, stylesheets, Javascript code uploaded to assets or to static resources. The syntax is a little bit different: for content asset archive file you need to concatenate asset name with pathinarchive  parameter and path value as follows “{!$ContentAsset.name + ‘pathinarchive=<path>’}” while for static resources, a resource name is concatenated directly with the following path “{!$Resource.name + ‘/<path‘}”.

The Label provider enables developers to access custom label values stored in Salesforce inside available from Tooling API ExternalString standard object. The syntax for the default namespace is  {!$Label.c.name} or $A.get(“$Label.c.name“) in Javascript, while for an organization with namespace the letter c should be replaced by namespace {!$Label.namespace.name} or $A.get(“$Label.namespace.name“).

The Locale provider supplies the information about the current Salesforce user’s local settings like country, currency, currency code, decimal separator, the first day of the week, the grouping separator, language, the full and short names of the calendar months and week days, the time zone and the formats for different types.

Custom value providers

Sometimes there appears a need to refine our code for the sake of development process acceleration or we might need some functionality which is not covered by standard value providers. In those cases we may opt for custom value providers.

The most interesting part here is the ability to define some custom value provider for a component. For example, in Visualforce it was possible to access map elements dynamically by means of syntax {!map[mapIndex]} but nothing similar is available in Lightning yet. However, we can implement a custom provider to iterate over a map in Lightning.

Let’s define a simple Iter.app and put the following code in its Javascript controller:

init: function(component, event, helper) {
     component.addValueProvider(
         ‘i’,
         {
             get: function(key, comp) {
                 let localMap = component.get(“v.”+key);
                 return Object.keys(localMap).map(key => localMap[key]);
             },
         }
     );
     component.set(‘v.providersAdded’, true);
}

Now let’s put the following markup in the app itself

<aura:attribute name=”providersAdded” default=”false” type=”Boolean” />
 <aura:handler name=”init” value=”{!this}” action=”{!c.init}” />
 <aura:attribute name=”mymap” type=”Map” default=”{‘name’:’France’,’capital’:’Paris’}”/>   
 <aura:if isTrue=”{!v.providersAdded}”>
 <!–Note the use of the special value provider that allows Map iteration–>
 <aura:iteration items=”{!i.mymap}” var=”value”>
     <div >{!value}</div>
     </aura:iteration>
 </aura:if>

Though `Mymap` attribute is a map in this code, we can still iterate over its values using aura:iteration like over an array. Did you notice which prefix is used here? It is important that the declaration of this attribute uses prefix i instead of default standard prefix v, which instructs Salesforce to use a custom value provider instead of standard component view provider. Custom value provider is supposed to have at least a getter to provide read-only data and an optional setter to allow data to be set.

Let’s have a look at another example which will also set data to custom value provider.

We could use custom value provider to store data in sessionStorage or localStorage. When setting data in session storage, the value is kept for the current page or tab and is deleted when a user closes the tab or page. Local storage shares data between tabs and is not deleted until the data value is explicitly cleared. In order to provide a convenient way for setting and retrieving data from a session or a local storage, we should add this code to Javascript controller:


component.addValueProvider(
      ‘storage’,
      {
          get: function(key, comp) {
              return sessionStorage.getItem(key);
          },
          set: function(key, value, comp) {
              sessionStorage.setItem(key, value);
          }
      }
  );
   
  component.addValueProvider(
      ‘localstorage’,
      {
          get: function(key, comp) {
              return localStorage.getItem(key);
          },
          set: function(key, value, comp) {
              localStorage.setItem(key, value);
          }
      }
  );

And similarly, to the Lightning standalone app itself:

Session storage: value kept on this page/tab <ui:inputText value=”{!storage.value}” /> <br/>
Local storage: value shared between tabs <ui:inputText value=”{!localstorage.value}” />

 

Did you notice which prefixes are used in the code snippet? Binding expressions use `localStorage.` and `storage.` prefixes to instruct Salesforce to use our custom value providers defined in Javascript controller for data storage, retrieval and access instead of standard component view provider.

To sum up, we have explored both standard and custom value providers usage and implementation options. Additionally, a difference between bound and unbound expressions is explained here.

Standard component value providers give an access to component data and allow to bind controller actions for event handling which are basic requirements for Junior Developers to their everyday Lightning development.

Standard global value providers expose some specific features like global automatically generated component identifier, operating system, and device detection as well as static images, Javascript and CSS code stored in Static Resources or Content Assets. They also provide access to static texts stored in Custom labels which can be translated and displayed in the user’s language alongside user profile’s locale data. Those are the tasks of an average complexity required to be performed by Junior or Middle Developers for their successful Lightning development.

Custom value providers extend the features provided by standard providers and might be used for more complicated tasks by Middle or Senior Developers.

Other articles

or

Book a meeting

Call (Toll-Free*) +1 (800) 917-0207

Zoom 30 min

* US and Canada, exceptions apply

Ready to innovate your business?

We are! Let’s kick-off our journey to success!